peertube.conf (13108B)
1 # PeerTube nginx configuration with S3 caching 2 # Based on upstream PeerTube S3 proxy documentation 3 # Adapted for sidecar deployment proxying both PeerTube and S3 4 5 proxy_cache_path /var/cache/nginx/s3 levels=1:2 keys_zone=CACHE-S3:100m inactive=48h max_size=10G; 6 proxy_cache_path /var/cache/nginx/s3-ts levels=1:2 keys_zone=CACHE-S3-TS:10m inactive=60s max_size=1G; 7 8 upstream peertube_backend { 9 server 127.0.0.1:9000; 10 } 11 12 server { 13 listen 8080; 14 server_name _; 15 16 access_log /var/log/nginx/peertube.access.log; 17 error_log /var/log/nginx/peertube.error.log; 18 19 # Performance optimizations 20 tcp_nopush on; 21 tcp_nodelay on; 22 keepalive_timeout 30; 23 client_body_timeout 30s; 24 client_header_timeout 10s; 25 send_timeout 10s; 26 reset_timedout_connection on; 27 proxy_ignore_client_abort on; 28 29 # Gzip compression 30 gzip on; 31 gzip_vary on; 32 gzip_types text/css application/javascript font/truetype font/opentype application/vnd.ms-fontobject image/svg+xml application/xml; 33 gzip_min_length 1000; 34 gzip_buffers 16 8k; 35 gzip_comp_level 2; 36 37 # S3 backend configuration (environment variables substituted by nginx) 38 set $s3_backend '${S3_ENDPOINT}'; 39 set $s3_host '${S3_HOST}'; 40 41 ## 42 # PeerTube API and Application 43 ## 44 45 location @api { 46 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 47 proxy_set_header Host $host; 48 proxy_set_header X-Real-IP $remote_addr; 49 50 client_max_body_size 100k; 51 52 proxy_connect_timeout 10m; 53 proxy_send_timeout 10m; 54 proxy_read_timeout 10m; 55 send_timeout 10m; 56 57 proxy_pass http://peertube_backend; 58 } 59 60 location / { 61 try_files /dev/null @api; 62 } 63 64 # Resumable uploads 65 location ~ ^/api/v1/videos/(upload-resumable|([^/]+/source/replace-resumable))$ { 66 client_max_body_size 0; 67 proxy_request_buffering off; 68 69 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 70 proxy_set_header Host $host; 71 proxy_set_header X-Real-IP $remote_addr; 72 proxy_connect_timeout 10m; 73 proxy_send_timeout 10m; 74 proxy_read_timeout 10m; 75 send_timeout 10m; 76 proxy_pass http://peertube_backend; 77 } 78 79 location ~ ^/api/v1/users/[^/]+/imports/import-resumable$ { 80 client_max_body_size 0; 81 proxy_request_buffering off; 82 83 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 84 proxy_set_header Host $host; 85 proxy_set_header X-Real-IP $remote_addr; 86 proxy_connect_timeout 10m; 87 proxy_send_timeout 10m; 88 proxy_read_timeout 10m; 89 send_timeout 10m; 90 proxy_pass http://peertube_backend; 91 } 92 93 # Video uploads 94 location ~ ^/api/v1/videos/(upload|([^/]+/studio/edit))$ { 95 limit_except POST HEAD { deny all; } 96 client_max_body_size 12G; 97 add_header X-File-Maximum-Size 8G always; 98 proxy_request_buffering off; 99 100 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 101 proxy_set_header Host $host; 102 proxy_set_header X-Real-IP $remote_addr; 103 proxy_connect_timeout 10m; 104 proxy_send_timeout 10m; 105 proxy_read_timeout 10m; 106 send_timeout 10m; 107 proxy_pass http://peertube_backend; 108 } 109 110 # Runner job updates 111 location ~ ^/api/v1/runners/jobs/[^/]+/(update|success)$ { 112 client_max_body_size 0; 113 proxy_request_buffering off; 114 115 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 116 proxy_set_header Host $host; 117 proxy_set_header X-Real-IP $remote_addr; 118 proxy_connect_timeout 10m; 119 proxy_send_timeout 10m; 120 proxy_read_timeout 10m; 121 send_timeout 10m; 122 proxy_pass http://peertube_backend; 123 } 124 125 # Other media uploads 126 location ~ ^/api/v1/(videos|video-playlists|video-channels|users/me) { 127 client_max_body_size 12M; 128 add_header X-File-Maximum-Size 8M always; 129 130 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 131 proxy_set_header Host $host; 132 proxy_set_header X-Real-IP $remote_addr; 133 proxy_connect_timeout 10m; 134 proxy_send_timeout 10m; 135 proxy_read_timeout 10m; 136 send_timeout 10m; 137 proxy_pass http://peertube_backend; 138 } 139 140 ## 141 # WebSocket support 142 ## 143 144 location /socket.io { 145 proxy_http_version 1.1; 146 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 147 proxy_set_header Host $host; 148 proxy_set_header X-Real-IP $remote_addr; 149 proxy_set_header Upgrade $http_upgrade; 150 proxy_set_header Connection "upgrade"; 151 proxy_pass http://peertube_backend; 152 } 153 154 location /tracker/socket { 155 proxy_http_version 1.1; 156 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 157 proxy_set_header Host $host; 158 proxy_set_header X-Real-IP $remote_addr; 159 proxy_set_header Upgrade $http_upgrade; 160 proxy_set_header Connection "upgrade"; 161 proxy_read_timeout 15m; 162 proxy_pass http://peertube_backend; 163 } 164 165 location ~ ^/plugins/[^/]+(/[^/]+)?/ws/ { 166 proxy_http_version 1.1; 167 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 168 proxy_set_header Host $host; 169 proxy_set_header X-Real-IP $remote_addr; 170 proxy_set_header Upgrade $http_upgrade; 171 proxy_set_header Connection "upgrade"; 172 proxy_pass http://peertube_backend; 173 } 174 175 ## 176 # Static media routing to S3 177 ## 178 179 # Private content goes through PeerTube for auth 180 location ~ ^(/static/(webseed|web-videos|streaming-playlists/hls)/private/)|^/download { 181 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 182 proxy_set_header Host $host; 183 proxy_set_header X-Real-IP $remote_addr; 184 proxy_limit_rate 5M; 185 proxy_pass http://peertube_backend; 186 } 187 188 # M3U8 and JSON files - no cache (for live streaming) 189 location ~ ^/static/.*\.(json|m3u8)$ { 190 limit_except GET OPTIONS { 191 deny all; 192 } 193 194 # Strip /static/ prefix for S3 path 195 rewrite ^/static/(.*)$ /$1 break; 196 197 resolver 1.1.1.1 8.8.8.8; 198 proxy_set_header Host $s3_host; 199 proxy_set_header Connection ''; 200 proxy_set_header Authorization ''; 201 proxy_set_header Range $http_range; 202 proxy_hide_header Set-Cookie; 203 proxy_hide_header 'Access-Control-Allow-Origin'; 204 proxy_hide_header 'Access-Control-Allow-Methods'; 205 proxy_hide_header 'Access-Control-Allow-Headers'; 206 proxy_hide_header x-amz-id-2; 207 proxy_hide_header x-amz-request-id; 208 proxy_hide_header x-amz-meta-server-side-encryption; 209 proxy_hide_header x-amz-server-side-encryption; 210 proxy_hide_header x-amz-bucket-region; 211 proxy_hide_header x-amzn-requestid; 212 proxy_ignore_headers Set-Cookie; 213 proxy_pass $s3_backend; 214 proxy_intercept_errors off; 215 216 expires 0; 217 proxy_cache off; 218 219 add_header 'Access-Control-Allow-Origin' '*'; 220 add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS'; 221 add_header 'Access-Control-Allow-Headers' 'Range,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'; 222 add_header X-Cache-Status $upstream_cache_status; 223 add_header X-Content-Type-Options nosniff; 224 add_header Content-Security-Policy "default-src 'none'; form-action 'none'"; 225 } 226 227 # .ts files for live streaming - short cache 228 location ~ ^/static/.*\.ts$ { 229 limit_except GET OPTIONS { 230 deny all; 231 } 232 233 # Strip /static/ prefix for S3 path 234 rewrite ^/static/(.*)$ /$1 break; 235 236 resolver 1.1.1.1 8.8.8.8; 237 proxy_set_header Host $s3_host; 238 proxy_set_header Connection ''; 239 proxy_set_header Authorization ''; 240 proxy_set_header Range $slice_range; 241 proxy_hide_header Set-Cookie; 242 proxy_hide_header 'Access-Control-Allow-Origin'; 243 proxy_hide_header 'Access-Control-Allow-Methods'; 244 proxy_hide_header 'Access-Control-Allow-Headers'; 245 proxy_hide_header x-amz-id-2; 246 proxy_hide_header x-amz-request-id; 247 proxy_hide_header x-amz-meta-server-side-encryption; 248 proxy_hide_header x-amz-server-side-encryption; 249 proxy_hide_header x-amz-bucket-region; 250 proxy_hide_header x-amzn-requestid; 251 proxy_ignore_headers Set-Cookie; 252 proxy_pass $s3_backend; 253 proxy_intercept_errors off; 254 255 proxy_cache CACHE-S3-TS; 256 proxy_cache_valid 200 206 2m; 257 proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504; 258 slice 1m; 259 proxy_cache_key $host$uri$is_args$args$slice_range; 260 proxy_http_version 1.1; 261 262 expires 1y; 263 add_header Cache-Control public; 264 add_header 'Access-Control-Allow-Origin' '*'; 265 add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS'; 266 add_header 'Access-Control-Allow-Headers' 'Range,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'; 267 add_header X-Cache-Status $upstream_cache_status; 268 add_header X-Content-Type-Options nosniff; 269 add_header Content-Security-Policy "default-src 'none'; form-action 'none'"; 270 } 271 272 # Map old webseed path to web-videos 273 location ~ ^/static/webseed/ { 274 limit_except GET OPTIONS { 275 deny all; 276 } 277 278 # Rewrite webseed to web-videos for S3 279 rewrite ^/static/webseed/(.*)$ /web-videos/$1 break; 280 281 resolver 1.1.1.1 8.8.8.8; 282 proxy_set_header Host $s3_host; 283 proxy_set_header Connection ''; 284 proxy_set_header Authorization ''; 285 proxy_set_header Range $slice_range; 286 proxy_hide_header Set-Cookie; 287 proxy_hide_header 'Access-Control-Allow-Origin'; 288 proxy_hide_header 'Access-Control-Allow-Methods'; 289 proxy_hide_header 'Access-Control-Allow-Headers'; 290 proxy_hide_header x-amz-id-2; 291 proxy_hide_header x-amz-request-id; 292 proxy_hide_header x-amz-meta-server-side-encryption; 293 proxy_hide_header x-amz-server-side-encryption; 294 proxy_hide_header x-amz-bucket-region; 295 proxy_hide_header x-amzn-requestid; 296 proxy_ignore_headers Set-Cookie; 297 proxy_pass $s3_backend; 298 proxy_intercept_errors off; 299 300 proxy_cache CACHE-S3; 301 proxy_cache_valid 200 206 48h; 302 proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504; 303 slice 1m; 304 proxy_cache_key $host$uri$is_args$args$slice_range; 305 proxy_http_version 1.1; 306 307 expires 1y; 308 add_header Cache-Control public; 309 add_header 'Access-Control-Allow-Origin' '*'; 310 add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS'; 311 add_header 'Access-Control-Allow-Headers' 'Range,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'; 312 add_header X-Cache-Status $upstream_cache_status; 313 add_header X-Content-Type-Options nosniff; 314 add_header Content-Security-Policy "default-src 'none'; form-action 'none'"; 315 } 316 317 # Public static content - route to S3 cache with long cache 318 location ~ ^/static/ { 319 limit_except GET OPTIONS { 320 deny all; 321 } 322 323 # Strip /static/ prefix for S3 path 324 rewrite ^/static/(.*)$ /$1 break; 325 326 resolver 1.1.1.1 8.8.8.8; 327 proxy_set_header Host $s3_host; 328 proxy_set_header Connection ''; 329 proxy_set_header Authorization ''; 330 proxy_set_header Range $slice_range; 331 proxy_hide_header Set-Cookie; 332 proxy_hide_header 'Access-Control-Allow-Origin'; 333 proxy_hide_header 'Access-Control-Allow-Methods'; 334 proxy_hide_header 'Access-Control-Allow-Headers'; 335 proxy_hide_header x-amz-id-2; 336 proxy_hide_header x-amz-request-id; 337 proxy_hide_header x-amz-meta-server-side-encryption; 338 proxy_hide_header x-amz-server-side-encryption; 339 proxy_hide_header x-amz-bucket-region; 340 proxy_hide_header x-amzn-requestid; 341 proxy_ignore_headers Set-Cookie; 342 proxy_pass $s3_backend; 343 proxy_intercept_errors off; 344 345 proxy_cache CACHE-S3; 346 proxy_cache_valid 200 206 48h; 347 proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504; 348 slice 1m; 349 proxy_cache_key $host$uri$is_args$args$slice_range; 350 proxy_http_version 1.1; 351 352 expires 1y; 353 add_header Cache-Control public; 354 add_header 'Access-Control-Allow-Origin' '*'; 355 add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS'; 356 add_header 'Access-Control-Allow-Headers' 'Range,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'; 357 add_header X-Cache-Status $upstream_cache_status; 358 add_header X-Content-Type-Options nosniff; 359 add_header Content-Security-Policy "default-src 'none'; form-action 'none'"; 360 } 361 }