Nginx Video on Demand Caching
Nginx setup for man-in-the-middle caching of video files.
# nginx virtual host configuration for content.example.com
# Filename: /etc/nginx/sites-enabled/content.example.com
# Video on Demand proxy cache
# Proxy cache location and details:
# use_temp_path=off - download directly into cache dir
# levels=1:2
# keys_zone=cache:32m - due to range caching, we need larger cache to track more objects
# inactive=1d - expire all content every 24 hours, upstream video may change
# max_size=50g;
proxy_cache_path /tmp/ng-cache use_temp_path=off levels=1:2 keys_zone=cache:32m inactive=1d max_size=50g;
server {
listen 443 ssl;
# Hostname of the original content server we are caching
server_name content.example.com;
# No local content is served, only proxy caching
root /dev/null;
location / {
# Backend original content server (AWS CloudFront)
proxy_pass https://content.example.com;
# AWS CloudFront requires us to pass hostname in the request for SNI to work
proxy_ssl_server_name on;
# Enable caching, ignore query string in cache
proxy_cache cache;
proxy_cache_key $host$uri$slice_range;
# Never serve cached content to unauth users, revalidate all requests with OCS
proxy_cache_valid 200 206 1s;
proxy_cache_revalidate on;
proxy_cache_use_stale error timeout updating;
# Permit a single backend request during cache update, hold other requests
# If multiple users concurrently access uncached video, this ensures a single request
# is sent to the OCS while all users requests are queued and then served from cache
proxy_cache_lock on;
# Break backend response (videos) into 1MB chunks for caching
slice 1m;
proxy_set_header Range $slice_range;
# DEBUG: Value must always be "REVALIDATED" or "MISS"
add_header X-Cache-Status $upstream_cache_status;
}
# DEBUG: Use self-signed certs
include snippets/snakeoil.conf;
# DEBUG: Remove this in production
access_log /var/log/nginx/cache-server-access.log;
error_log /var/log/nginx/cache-server-error.log;
}
# Redirect all http requests to https
server {
listen 80;
server_name content.example.com;
return 301 https://$server_name$request_uri;
}