From Localhost to Production: Deploying Django + React with HTTPS and Nginx
The “Oh Crap, Now What?” Moment
So there I was, staring at my laptop. My Django backend was beautiful. My React frontend was polished. Users could log in, make calls, chat — everything worked perfectly.
On localhost.
My friend asked: “When are you launching?”
Launch. As in, put it on the actual internet. Where real people can access it. Where if something breaks, thousands of people see it break.
“Uh… soon?” I said nervously.
I had no idea what I was doing.
I Googled “deploy Django and React to production.” Found 47 different tutorials with 47 different opinions. Some mentioned Docker. Others mentioned Kubernetes. One suggested AWS with microservices.
I closed my laptop and ate ice cream instead.
But eventually, I had to bite the bullet. I bought a domain name. Rented a server. And figured out how to get my app online with HTTPS so users could actually use it.
This is that story. And honestly? It’s not as scary as I thought.
Let me walk you through it so you don’t have to panic-eat ice cream like I did.
What “Production” Actually Means
Before we deploy, let’s clarify what we’re doing.
Development (what you’ve been doing):
Your laptop
→ localhost:3000 (React)
→ localhost:8000 (Django)
→ Everything works, nothing is secure, only you can access itProduction (what we’re building):
Real server on the internet
→ https://yourdomain.com (React)
→ https://yourdomain.com/api/ (Django)
→ HTTPS encryption, real SSL certificate, anyone can access itThe difference? A server on the internet running 24/7, with SSL encryption so data is secure.
The Production Stack (Like Assembling a Team)
Here’s what we need:
React (Frontend) — The pretty interface users see
Django (Backend) — The brain handling data and logic
Daphne (ASGI Server) — The engine running Django
Nginx (Reverse Proxy) — The receptionist handling traffic
SSL Certificate (Encryption) — The lock keeping data safe
Think of it like a restaurant:
- React = The dining room (what customers see)
- Django = The kitchen (where the work happens)
- Daphne = The cook
- Nginx = The manager directing traffic
- SSL = The vault protecting customer data
They all work together to serve customers (users) safely.
The Scary Part: Renting a Server
I bought a domain name on GoDaddy ($12/year).
Then I rented a server. I chose DigitalOcean because:
- It’s beginner-friendly
- Cheap ($5/month for a basic droplet)
- Great documentation
- No vendor lock-in
You could also use:
- AWS (powerful, complicated)
- Heroku (expensive but easier)
- Linode (similar to DigitalOcean)
- Render (good for hobby projects)
I created a basic Ubuntu 20.04 server (called a “droplet” on DigitalOcean).
Now I had a blank Linux server sitting on the internet, waiting for me to do something with it.
No pressure.
Step 1: Connecting to Your Server
You’ll get an IP address like 192.168.1.100.
Connect via SSH (secure shell):
ssh root@your-server-ipIt asks for a password. Enter it.
Congratulations — you’re now inside a Linux server on the internet. Everything you type affects a real computer somewhere.
Don’t break it.
First thing: update the system.
sudo apt update
sudo apt upgrade -yThis installs the latest security patches. Boring but important.
Step 2: Installing the Tools
Install Python:
sudo apt install python3 python3-pip python3-venv -yInstall Node.js:
sudo apt install nodejs npm -yThese are the foundations. Python runs Django. Node runs React.
Verify they’re installed:
python3 --version
node --versionIf you see version numbers, you’re good.
Step 3: Getting Your Code On the Server
Here’s where it gets real. You need to get your Django and React code from your laptop to the server.
Options:
- Git (recommended) — Push code to GitHub, pull it on the server
- SCP — Copy files directly
- Docker — Package everything (advanced)
I used Git. It’s the professional way:
bash
# On the server
cd /var/www
git clone https://github.com/yourusername/your-project.git
cd your-projectNow your code is on the server.
Step 4: Setting Up Django
Navigate to your Django project:
cd backend
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
pip install daphneThis installs your Python dependencies and Daphne.
Update settings.py for production:
DEBUG = False # CRITICAL: Never leave this True in productionALLOWED_HOSTS = [
"yourdomain.com",
"www.yourdomain.com"
]STATIC_ROOT = "/var/www/your-project/static"
STATIC_URL = "/static/"
Then collect static files:
python manage.py collectstatic --noinputThis gathers all your CSS, JavaScript, images into one place so Nginx can serve them fast.
Step 5: Building React for Production
Go to your React folder:
cd ../frontend
npm install
npm run buildThis creates an optimized build/ folder with your entire React app compressed and ready to serve.
The build folder is what users will actually download.
Step 6: Installing Nginx (The Traffic Director)
sudo apt install nginx -y
sudo systemctl start nginx
sudo systemctl enable nginxNginx is a lightweight web server that acts as a reverse proxy. It:
- Handles HTTPS encryption
- Serves your React static files
- Routes API requests to Django
- Handles tons of traffic efficiently
Think of it as a receptionist that:
- Takes incoming requests
- Sends them to the right person (React files or Django API)
- Wraps everything in encryption
Step 7: Configuring Nginx
This is where it comes together.
Create a new configuration file:
sudo nano /etc/nginx/sites-available/myprojectPaste this:
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;# Serve React frontend
location / {
root /var/www/your-project/frontend/build;
try_files $uri /index.html;
}
# Route API requests to Django
location /api/ {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# Serve Django static files
location /static/ {
alias /var/www/your-project/static/;
}
}
What’s This Doing?
Line 2: Listen on port 80 (HTTP, before HTTPS)
Line 3: Your domain name
Lines 6–10: Serve React files from the build folder
Lines 12–17: Route /api/ requests to Django on port 8000
Lines 19-21: Serve Django static files directly (fast)
Get Oviyan S’s stories in your inbox
Join Medium for free to get updates from this writer.
Enable this configuration:
sudo ln -s /etc/nginx/sites-available/myproject \
/etc/nginx/sites-enabled/Test for errors:
sudo nginx -tIf you see “test successful,” reload:
sudo systemctl reload nginxNow visit your server IP in a browser. You should see your React app!
Step 8: Adding HTTPS (The Security Part)
This is the best part — free SSL certificates using Let’s Encrypt.
Install Certbot:
sudo apt install certbot python3-certbot-nginx -yGenerate your certificate:
sudo certbot --nginxCertbot will:
- Ask for your email
- Ask you to agree to terms
- Ask which domains to secure
- Automatically configure HTTPS
- Automatically redirect HTTP to HTTPS
After it finishes, your nginx config is automatically updated with HTTPS settings.
Magic.
Visit https://yourdomain.com
Check the address bar. You should see:
- 🔒 lock icon
https://in green- No security warnings
Your app is now encrypted. Data traveling between users and your server is secure.
Step 9: Starting Django (The Engine)
Now we need Django running in the background, handling API requests.
Activate the virtual environment and start Daphne:
bash
cd /var/www/your-project/backend
source venv/bin/activate
daphne -b 127.0.0.1 -p 8000 myproject.asgi:applicationBut wait — if you close your SSH connection, Django stops.
We need to keep it running forever. That’s where systemd comes in.
Create a service file:
sudo nano /etc/systemd/system/django.servicePaste this:
[Unit]
Description=Django ASGI Service
After=network.target
[Service]
Type=notify
User=www-data
WorkingDirectory=/var/www/your-project/backend
Environment="PATH=/var/www/your-project/backend/venv/bin"
ExecStart=/var/www/your-project/backend/venv/bin/daphne \
-b 127.0.0.1 -p 8000 myproject.asgi:application
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.targetEnable and start:
sudo systemctl daemon-reload
sudo systemctl enable django
sudo systemctl start djangoNow Django runs automatically. Even if the server reboots, it restarts itself.
Check status:
sudo systemctl status djangoShould say “active (running)”.
Step 10: Fixing Common Issues
1. “Microphone/Camera Not Working”
Make sure your React code makes API calls to https://yourdomain.com/api/, not http://.
In your React code:
javascript
// Wrong
const response = await fetch('http://yourdomain.com/api/');// Right
const response = await fetch('https://yourdomain.com/api/');Mixed HTTP/HTTPS causes browsers to block requests.
2. “Static Files Look Broken”
Run on your server:
python manage.py collectstatic --noinputThen restart Django:
sudo systemctl restart django3. “Getting 502 Bad Gateway”
This means Nginx can’t reach Django. Check if Django is running:
sudo systemctl status djangoIf it’s down, check the logs:
sudo journalctl -u django -n 50The error message usually tells you what’s wrong.
4. “Domain Not Working”
Your domain needs to point to your server’s IP. Go to your registrar (GoDaddy, Namecheap, etc.) and add an A record:
A record: yourdomain.com → your-server-ip
A record: www.yourdomain.com → your-server-ipWait 15–30 minutes for DNS to propagate.
What We Just Accomplished
Let’s appreciate what happened:
- Rented a real server — Your app is on the internet
- Installed tools — Python, Node, Nginx, Daphne
- Deployed code — React and Django are live
- Configured Nginx — Traffic routing works
- Added HTTPS — Free SSL certificate from Let’s Encrypt
- Started Django — Backend running 24/7
- Secured everything — Users can’t intercept your data
Your app is now live on the internet with real HTTPS encryption.
The Mental Model
Think of your production setup like a real store:
React = The storefront (what customers see in the window)
Django = The warehouse (inventory, processing orders)
Nginx = The manager (directing customers to right department, handling payments)
Daphne = The warehouse worker (actually fulfilling orders)
HTTPS = The security system (protecting customer data)
All working together to serve customers safely.
What You Learned
You now know:
- How to rent a server
- How to install production tools
- How to configure Nginx as a reverse proxy
- How to get free HTTPS with Let’s Encrypt
- How to keep your app running 24/7
- Common deployment issues and fixes
This isn’t beginner knowledge anymore. This is professional deployment knowledge.
The Victory Lap
When I first deployed, I was terrified. What if I broke something? What if no one could access it?
But then I sent my friend the link: https://yourdomain.com
They clicked it from their phone.
My app loaded.
They could log in, make calls, everything worked.
“Dude, this is actually online,” they said.
Best feeling ever.
All that complexity — servers, Nginx, DNS, SSL certificates, systemd — it all just… worked.
And the beautiful part? Once you’ve done it once, deploying is easy. Future projects just follow the same pattern.
Questions? Drop a comment:
- Did you deploy your first app?
- What broke and how did you fix it?
- What’s your next project?
- Want me to show you automated deployment or Docker?
You didn’t just build an app. You shipped it to production. That’s not small.
Most people never get here. You did.
Let me know what you’re building!










