Deploy Django on Oracle Cloud Free Tier
Deploy Django on Oracle Cloud Always Free resources: create an Ampere A1 Arm instance, open ports in both the security list and the instance iptables, install the stack on Ubuntu, and know the free tier's limits and reclaim rules.
Problem statement
Oracle Cloud Infrastructure's Always Free tier includes Arm-based Ampere A1 compute with up to 4 OCPUs and 24 GB of memory in total, which is far more than other free offers and plenty for a side project or small production Django site. The catch is setup friction: capacity is sometimes unavailable in popular regions, networking requires opening ports in two separate places, the default images ship with restrictive iptables rules, and idle free instances can be reclaimed. This guide gets a Django app running there and avoids the usual traps.
- Create an Always Free Ampere A1 instance (for example 2 OCPU, 12 GB) with Ubuntu 24.04 (aarch64) and your SSH key.
- Add ingress rules for TCP 80 and 443 to the subnet's security list or a network security group.
- Also open 80 and 443 in the instance's iptables (Ubuntu images on OCI ship with a REJECT rule) and save them.
- Install PostgreSQL, Python, Gunicorn, and Nginx; Arm wheels exist for nearly all common packages.
- Point DNS at the public IP (reserve it so it does not change) and run Certbot.
- Keep backups off the instance, and understand the idle reclamation policy for free instances.
Step-by-step solution
1. Create the instance
In the OCI console: Compute → Instances → Create. Choose an Always Free eligible shape: VM.Standard.A1.Flex, set OCPUs and memory within the free allowance, select the Canonical Ubuntu 24.04 image (aarch64), and upload your SSH key. If you get "Out of capacity", try another availability domain or retry later; popular home regions can be full.
Reserve a public IP (Networking → Reserved public IPs) and assign it, so rebuilding the instance does not change your DNS.
2. Open ports in the VCN
The subnet's security list (or an NSG on the VNIC) controls traffic before it reaches the VM. Add stateful ingress rules:
- Source
0.0.0.0/0, TCP, destination port 80. - Source
0.0.0.0/0, TCP, destination port 443.
SSH (22) is open by default; restrict it to your IP.
3. Open ports on the instance
OCI's Ubuntu images include iptables rules that reject everything except SSH, in addition to the security list. Insert accept rules before the reject rule and persist them:
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
sudo iptables -L INPUT --line-numbers
Check the line number of the REJECT rule in your image and insert above it. Do not enable ufw on top of these rules without understanding the interaction; manage one firewall tool consistently.
4. Install the Django stack
sudo apt update
sudo apt install -y python3-venv python3-dev build-essential libpq-dev postgresql nginx
Then follow the standard layout: a deploy user, the project in /srv/app, a virtualenv, an environment file, Gunicorn under systemd on a Unix socket, and Nginx in front; see Deploy Django With Gunicorn and Nginx on Ubuntu. Python packages such as psycopg, Pillow, lxml, and cryptography publish aarch64 wheels, so installs are fast. If you build Docker images, build them for linux/arm64.
With 12-24 GB of memory available, you can comfortably run PostgreSQL, Redis, Celery, and several Gunicorn workers on one instance.
5. DNS and HTTPS
Point an A record at the reserved IP, then:
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com
6. Backups and the reclaim policy
Free tier resources come with conditions. Oracle documents that Always Free compute instances can be reclaimed if they are idle (very low CPU, network, and memory use over a sustained period). A site with real traffic is not idle, but a test instance may be. Upgrading the account to Pay As You Go keeps the free allowances while removing idle reclamation for those resources; check Oracle's current terms.
Either way, keep backups elsewhere: nightly pg_dump to OCI Object Storage (part of the free allowance) or another provider, and keep your server setup scripted so you can rebuild quickly.
Verification check: from outside, curl -I https://example.com returns 200; sudo iptables -L INPUT -n shows ACCEPT rules for 80 and 443 above the REJECT; a restore of the latest backup into a scratch database works.
Explanation
OCI separates network security (security lists and NSGs on the virtual cloud network) from host security, and its platform images add a host firewall that denies inbound traffic by default. Both layers must allow web traffic, which is unusual compared with providers whose images ship without host firewall rules. The Ampere A1 Arm processors run standard Python and Django without changes; the only practical difference from x86 is building container images for the right architecture.
Edge cases / notes
- Outbound SMTP on port 25 is blocked by default; use an email API or port 587 with a provider.
- Capacity for A1 shapes varies by region; once you have an instance, keep it rather than deleting and recreating.
- Block volume free allowance is limited (around 200 GB total including boot volumes); watch disk use.
- Oracle Linux images use firewalld instead of iptables rules; open ports with
firewall-cmd.
Next steps
- Diagnose blocked traffic with Fix a Django Site That Runs but Cannot Be Reached.
- Building containers for Arm? See Build Multi-Arch Docker Images for Django.
FAQ
Is Oracle Cloud free tier good enough for Django production?
For small sites, yes: the Ampere A1 allowance is generous. Keep backups elsewhere and understand the reclaim policy.
Why can I not reach my site on Oracle Cloud?
Ports must be opened in both the VCN security list and the instance's iptables rules.
Does Django run on Arm processors?
Yes. Python, Django, and common packages publish aarch64 wheels.
Can a free instance be deleted?
Oracle may reclaim idle Always Free instances. Active sites are not idle, but keep backups and a rebuild script.