In modern web architecture, speed and scalability are non-negotiable. A CDN (Content Delivery Network) plays a critical role in improving site performance by delivering static assets closer to the end users. Delivering static assets (CSS, JavaScript, images) from a standalone CDN server can dramatically improve your site’s performance and reliability.
In this post, we’ll walk through setting up an AWS EC2 instance, hosting static files, serving them using Nginx, and dramatically improving their delivery speed using Cloudflare as a CDN.
Why a Separate CDN Server?
- Isolation of concerns: Your web and app servers handle dynamic traffic, while your CDN server exclusively serves static content.
- Scalability: You can scale or snapshot your CDN layer independently.
- Cache-control: Nginx and Cloudflare provide fine-grained caching without requiring changes to Django.
1. SSH into Your Server
Use your SSH key and the EC2 public IP to connect:
ssh -i path/to/your-key.pem ubuntu@YOUR_EC2_PUBLIC_IP
2. Installing Nginx & Preparing ~/static
Update your package list and install Nginx:
sudo apt update
sudo apt install -y nginx
Create the static files directory in your home folder:
mkdir -p ~/static
chown -R $USER:www-data ~/static
chmod -R 755 ~/static
Now /home/ubuntu/static is ready to receive your collected assets.
3. Nginx Configuration
# In your home directory, create a conf folder
mkdir -p ~/conf
cd ~/conf
# Edit your nginx.conf
vim nginx.conf
Inside ~/conf/nginx.conf, add:
server {
listen 80;
server_name cdn.example.com;
# Get real visitor IP from Cloudflare
real_ip_header CF-Connecting-IP;
set_real_ip_from 0.0.0.0/0;
# Serve static files from ~/static
___location / {
root /home/ubuntu;
try_files /static$uri =404;
# Cache for 7 days
expires 7d;
add_header Cache-Control "public, max-age=604800";
# No access logs for static files
access_log off;
}
# Let's Encrypt support
___location /.well-known/acme-challenge/ {
root /home/ubuntu;
}
# Health check
___location /health {
return 200 "OK";
access_log off;
}
}
Then activate it by symlinking into Nginx’s conf.d:
sudo ln -sf /home/ubuntu/conf/nginx.conf /etc/nginx/conf.d/cdn_nginx.conf
sudo nginx -t
sudo systemctl reload nginx
4. Pointing cdn.example.com to Your EC2 + Cloudflare
- In your DNS provider or Cloudflare, create an A record:
- Name: cdn
- Type: A
- Value: YOUR_EC2_PUBLIC_IP
- In Cloudflare’s dashboard, set Proxy status to Proxied. Requests to cdn.example.com will now route through Cloudflare’s edge network.
5. Syncing Your Static Files
rsync -av --delete path/to/local/static/ ubuntu@YOUR_EC2_PUBLIC_IP:/home/ubuntu/static/
-a preserves permissions
--delete removes files no longer present locally
Automate this step so every deployment populates your CDN.
6. Enabling HTTPS on the CDN Server
For Cloudflare’s Full (strict) SSL mode, install a Let’s Encrypt certificate:
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d cdn.example.com
Certbot will:
- Configure Nginx to listen on port 443
- Set up auto-renewal
- Redirect HTTP to HTTPS
7. Django Configuration
In your production settings (settings.py), set:
STATIC_URL = "https://cdn.example.com/"
No other Django changes are required. All {% static %}
tags will now reference your CDN host.
8. Verifying Cache & Performance
- Open Developer Tools - Network - reload a page with static assets.
- Inspect headers for CSS/JS files
cf-cache-status: HIT
cache-control: max-age=2592000
- In Cloudflare’s dashboard, review Cache Analytics. Aim for a high Hit Ratio.
9. Advanced Tips
- Cache Purge: Use Cloudflare’s API or dashboard to purge specific URLs after critical updates.
- Security: Lock down SSH via Cloudflare Firewall, and allow only trusted IPs.
Top comments (0)