Nginx is very good at serving HLS playback files when the playlist and segments already exist. For many business, training, church, event, course, and membership sites, that is the cleanest setup: generate the HLS files with your encoder or media workflow, then let Nginx serve the .m3u8 playlist and segment files quickly.
There are two different jobs people mix together. One is serving static HLS files. The other is generating HLS from source media or a live stream. Standard open source Nginx can serve the files. NGINX Plus includes an official HLS module for MP4/MOV server-side support. Community live-stream workflows often use a third-party module such as nginx-rtmp-module.
Static HLS file layout
A common HLS folder contains one playlist and many small media segments:
/var/www/video/hls/course-intro/
index.m3u8
segment-00001.ts
segment-00002.ts
segment-00003.ts
For fragmented MP4 HLS, you may see .m4s segments instead of .ts. The player loads the playlist first, then fetches segments as playback progresses.
Nginx config for HLS playback
server {
listen 443 ssl;
http2 on;
server_name video.example.com;
ssl_certificate /etc/letsencrypt/live/video.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/video.example.com/privkey.pem;
location /hls/ {
alias /var/www/video/hls/;
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
video/mp4 mp4 m4s;
}
add_header Access-Control-Allow-Origin "*" always;
add_header Cache-Control "public, max-age=60" always;
try_files $uri =404;
}
}
Use root or alias deliberately. With alias, the trailing slash matters. Test the exact playlist URL after every change.
Cache planning
For video on demand, longer cache times usually make sense after the files are final. For live or frequently replaced playlists, keep the playlist cache short and let segments cache longer. If a CDN sits in front of Nginx, purge or version playlists when replacing a video.
- Static VOD playlist: cache playlist and segments longer after publishing.
- Live playlist: keep playlist cache short so viewers receive fresh segment lists.
- Private content: avoid public cache unless authorization is handled at the CDN or application layer.
- Customer uploads: never expose a writable upload directory directly as an executable web path.
Playback verification
curl -I https://video.example.com/hls/course-intro/index.m3u8
curl -I https://video.example.com/hls/course-intro/segment-00001.ts
The playlist should return a normal 200 response and a playlist MIME type. The segment should return 200 and a video segment type. Test playback in Safari, VLC, or an HTML5 player that uses hls.js for browsers that do not play HLS natively.
When you need more than static files
If you want Nginx to create HLS playlists from MP4/MOV files on demand, read the official Nginx HLS module documentation and note that it is part of the commercial subscription. If you want live ingest, transcoding, DVR windows, or adaptive bitrate ladders, plan the encoder and streaming layer separately. Nginx can be the delivery piece, but it is not the whole media pipeline by itself.
Security and hosting notes
- Keep HLS storage outside application upload paths when possible.
- Do not serve private customer media from a public folder without authorization.
- Use HTTPS, especially when players are embedded on HTTPS websites.
- Check bandwidth and CDN billing before publishing large videos.
- Log 404s and 403s so broken playlists are easy to find.
Related Fix I.T. Phill guides
- Nginx HTTP/2 Modern Config Guide
- Certbot with Nginx: Let’s Encrypt Install and Renewal Guide
- Nginx WordPress Optimization: Best Configurations
- Help4 Network hosting and website support
