DEV Community

AJAYA SHRESTHA
AJAYA SHRESTHA

Posted on

Optimize Static Delivery: Host Static Assets on AWS EC2 with Nginx & Cloudflare

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 
Enter fullscreen mode Exit fullscreen mode

2. Installing Nginx & Preparing ~/static

Update your package list and install Nginx:

sudo apt update sudo apt install -y nginx 
Enter fullscreen mode Exit fullscreen mode

Create the static files directory in your home folder:

mkdir -p ~/static chown -R $USER:www-data ~/static chmod -R 755 ~/static 
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

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; } } 
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

4. Pointing cdn.example.com to Your EC2 + Cloudflare

  1. In your DNS provider or Cloudflare, create an A record:
  • Name: cdn
  • Type: A
  • Value: YOUR_EC2_PUBLIC_IP
  1. 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/ 
Enter fullscreen mode Exit fullscreen mode

-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 
Enter fullscreen mode Exit fullscreen mode

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/" 
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode
  • 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)