You’ve deployed a fresh Ubuntu 24.04 instance on Oracle Cloud Infrastructure (OCI), installed Nginx, and everything looks perfect.
Nginx starts, your app runs locally on http://127.0.0.1, but when you try http://your-public-ip, nothing happens.
Don’t worry — you’re not alone. This is one of the most common OCI setup issues, caused by layered firewalls and missing network rules.
In this guide, we’ll walk through the root causes and step-by-step fixes to make your Nginx web server publicly accessible on ports 80 and 443.
⚙️ Step 1 — Verify Nginx Is Running
Start by confirming that Nginx is up and listening:
sudo systemctl status nginx --no-pager
sudo ss -ltnp | egrep ':80|:443'
You should see something like:
LISTEN 0 511 0.0.0.0:80
LISTEN 0 511 [::]:80
If you see only 127.0.0.1:80, edit /etc/nginx/sites-enabled/default:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.html;
}
Reload Nginx:
sudo nginx -t && sudo systemctl reload nginx
Then test locally:
curl -I http://127.0.0.1
If you get HTTP/1.1 200 OK, Nginx is fine.
🔥 Step 2 — Check Ubuntu Firewall (UFW or iptables)
Many Oracle Ubuntu images ship without UFW, so if ufw isn’t found, use iptables.
Install and enable UFW (optional):
sudo apt update
sudo apt install ufw -y
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable
or flush existing iptables rules:
sudo iptables -F
sudo iptables -X
sudo iptables -t nat -F
sudo iptables -t nat -X
sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -P OUTPUT ACCEPT
Then test again from outside:
curl -I http://YOUR_PUBLIC_IP
If it works now, the block was in iptables.
To re-apply a safe firewall baseline:
sudo iptables -P INPUT DROP
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
sudo apt install netfilter-persistent -y
sudo netfilter-persistent save
☁️ Step 3 — Configure Oracle Cloud Networking
Oracle Cloud has its own firewall layers: VCN Security Lists or Network Security Groups (NSG).
✅ Checklist
- Public Subnet Routing
- Go to Networking → VCN → Subnets → Your Subnet
- Route Table must include
0.0.0.0/0 → Internet Gateway
- Security List or NSG Rules
Add the following Ingress Rules: Source CIDR Protocol Port Range Description 0.0.0.0/0 TCP 80 Allow HTTP 0.0.0.0/0 TCP 443 Allow HTTPS 0.0.0.0/0 TCP 22 Allow SSH If using an NSG, attach it to your instance’s VNIC. - Public IP
- Check that your VM’s primary VNIC has a Public IPv4 address.
🔎 Step 4 — Confirm Traffic Reaches the Instance
Run a live capture:
ip -br a
sudo tcpdump -i ens3 -n 'tcp port 80 or 443'
Then, from your laptop:
curl -I http://YOUR_PUBLIC_IP
- If you see packets in tcpdump → Ubuntu firewall issue.
- If you see nothing → OCI networking (Security List/NSG) issue.
🔒 Step 5 — Add HTTPS (Optional)
If you want HTTPS, you can test with a temporary self-signed certificate:
sudo openssl req -x509 -nodes -days 1 -newkey rsa:2048 \
-keyout /etc/nginx/self.key -out /etc/nginx/self.crt \
-subj "/CN=$(hostname -f)"
Add a 443 block in /etc/nginx/sites-enabled/default:
server {
listen 443 ssl http2;
server_name _;
ssl_certificate /etc/nginx/self.crt;
ssl_certificate_key /etc/nginx/self.key;
root /var/www/html;
}
Reload and verify:
sudo nginx -t && sudo systemctl reload nginx
sudo ss -ltnp | grep 443
curl -kI https://YOUR_PUBLIC_IP
✅ Step 6 — Final Verification
Once all layers are configured, your checklist should look like this:
| Layer | Status | Notes |
|---|---|---|
| Nginx | ✅ Running | 0.0.0.0:80 visible |
| OS Firewall | ✅ Ports 80/443 open | via UFW or iptables |
| OCI Security | ✅ Ingress rules added | HTTP, HTTPS allowed |
| Public IP | ✅ Assigned | Accessible via browser |
Finally, open your browser:
http://YOUR_PUBLIC_IP
You should see the “Welcome to Nginx” page 🎉.
💡 Common Pitfalls
- Private Subnet: Routes to NAT Gateway, not Internet Gateway.
- NSG attached but empty: Security List rules don’t apply if NSG exists.
- Loopback binding: Nginx only listening on
127.0.0.1. - Cloudflare Proxy: Test using the raw IP, not proxied domain.
🧠 Summary
When Nginx works locally but not from outside in Oracle Cloud, remember:
Oracle Cloud ≠ Just Ubuntu Firewall.
You need to allow traffic at four levels:
VCN → Subnet/NSG → OS Firewall → Nginx.