Skip to content

Instantly share code, notes, and snippets.

@ROBERT-MCDOWELL
Forked from rigelk/peertube.conf
Last active January 6, 2024 21:46
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ROBERT-MCDOWELL/0ed82ec304fa76de9ff52cc4a5a49e4c to your computer and use it in GitHub Desktop.
Save ROBERT-MCDOWELL/0ed82ec304fa76de9ff52cc4a5a49e4c to your computer and use it in GitHub Desktop.
Unofficial support of the last and updated httpd/Apache vhost to run PeerTube 5.x ONLY
# PeerTube Apache configuration version 24.1.6 (for PeerTube version 5.x only)
SSLSessionCache "shmcb:/usr/local/apache/logs/ssl_gcache_data(512000)"
SSLSessionCacheTimeout 87400
SSLStaplingCache shmcb:logs/stapling-cache(150000)
# Please check your Apache installation features the following modules via 'apachectl -M':
# STANDARD HTTP MODULES: core_module, proxy_module, proxy_http2_module, proxy_wstunnel_module, proxy_http_module, headers_module, remoteip_module, ssl_module, filter_module, reqtimeout_module
# THIRD PARTY MODULES: None.
# check https://ssl-config.mozilla.org/#server=apache&version=2.4.41&config=modern&openssl=1.1.1d&hsts=false&ocsp=false&guideline=5.6 for hardening security
SSLSessionCache "shmcb:/usr/local/apache/logs/ssl_gcache_data(512000)"
SSLSessionCacheTimeout 87400
SSLStaplingCache shmcb:logs/stapling-cache(150000)
ProxyPreserveHost On
ProxyRequests On
<VirtualHost *:80 [::]:80>
Protocols h2c http/1.1
ServerName peertube.example.com
ServerAdmin webmaster@example.com
ErrorLog "/var/log/httpd/[peertube.example.com].error.log"
CustomLog "/var/log/httpd/[peertube.example.com].access.log" common env=!dontlog
RewriteEngine on
RewriteOptions inherit
RewriteCond %{REQUEST_URI} !^/\.well\-known/acme\-challenge/
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Alias /.well-known/acme-challenge/ /var/www/certbot/
<Directory "/var/www/certbot">
Options None
AllowOverride None
ForceType text/plain
RedirectMatch 404 "^(?!/\.well-known/acme-challenge/[\w-]{43}$)"
Require method GET POST OPTIONS
</Directory>
</VirtualHost>
<VirtualHost *:443 [::]:443>
Protocols h2 h2c http/1.1 TLSv1.2 TLSv1.3 http/1.0
ProtocolsHonorOrder Off
ServerName example.com
ServerAlias peertube.example.com
SetEnv increaseTimeout false
RewriteEngine on
RewriteOptions inherit
CustomLog "/usr/local/apache/logs/peertube.access.log" common "env=!dontlog"
ErrorLog "/usr/local/apache/logs/example.com.error.log"
##
# Certificates
# you need a certificate to run in production. see https://letsencrypt.org/
##
SSLEngine on
SSLProxyEngine on
SSLCertificateFile /etc/letsencrypt/live/peertube.example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/peertube.example.com/privkey.pem
##
# Security hardening (as of Nov 15, 2020)
# based on Mozilla Guideline v5.6
##
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
# SSLCipherSuite: add ECDHE-RSA-AES256-SHA if you want compatibility with Android 4
SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
SSLHonorCipherOrder on
SSLSessionTickets off
SSLUseStapling on
Header set Strict-Transport-Security "max-age=8740000; includeSubDomains; preload"
Header set X-Content-Type-Options nosniff
Header set X-Robots-Tag none
Header set X-XSS-Protection "1; mode=block"
RequestHeader set Host expr=%{HTTP_HOST}
RequestHeader set X-Forwarded-For expr=%{REMOTE_ADDR}
RequestHeader set X-Real-IP expr=%{REMOTE_ADDR}
##
# Application
##
LimitRequestBody 102400
ProxyReceiveBufferSize 0
KeepAliveTimeout 10
ProxyTimeout 900
ProxyIOBufferSize 1024
ProxyIOBufferSize 1024
ProxyReceiveBufferSize 8192
<Location "/api/v1/videos/upload-resumable">
LimitRequestBody 0
</Location>
<LocationMatch "^/api/v1/videos/(upload|([^/]+/studio/edit))$">
Require all granted
<LimitExcept POST HEAD>
Require all denied
</LimitExcept>
# This is the maximum upload size, which roughly matches the maximum size of a video file.
# Note that temporary space is needed equal to the total size of all concurrent uploads.
# You may want to put this directory on a dedicated filesystem.
LimitRequestBody 12884901888
# inform backend of the set value in bytes before mime-encoding (x * 1.4 >= LimitRequestBody)
Header set X-File-Maximum-Size 8G
</LocationMatch>
<LocationMatch "^/api/v1/runners/jobs/[^/]+/(update|success)$">
LimitRequestBody 12884901888;
Header set X-File-Maximum-Size 8G always; # inform backend of the set value in bytes before mime-encoding (x * 1.4 >= client_max_body_size)
</LocationMatch>
<LocationMatch "^/api/v1/(videos/*/views|video-playlists|video-channels|users/me|metrics)*$">
LimitRequestBody 6291456
# inform backend of the set value in bytes before mime-encoding (x * 1.4 >= LimitRequestBody)
Header set X-File-Maximum-Size 4M
</LocationMatch>
##
# Performance optimizations
# Compression enabled automatically by filter_module
DocumentRoot /var/www/peertube
RequestReadTimeout body=30 header=10
Options +FollowSymLinks -SymLinksIfOwnerMatch
Alias /client %{DOCUMENT_ROOT}/peertube-latest/client/dist
# http/2 tuning
H2Push on
H2PushPriority * after
H2PushPriority txt/css before
H2PushPriority image/jpeg after 32
H2PushPriority image/png after 32
H2PushPriority application/javascript interleaved
# Bypass PeerTube for performance reasons. Optional.
# Should be consistent with client-overrides assets list in /server/controllers/client.ts
<LocationMatch "^/client/(.*\.(js|css|png|svg|woff2|otf|ttf|woff|eot))$">
# Cache 1 year
Header set Cache-Control "public, max-age=31536000, immutable"
RewriteRule ^/client/(.*)$ %{DOCUMENT_ROOT}/peertube-latest/client/dist/$1 [L]
</LocationMatch>
# Bypass PeerTube for performance reasons. Optional.
<LocationMatch "^/client/(assets/images/(icons/icon-36x36\.png|icons/icon-48x48\.png|icons/icon-72x72\.png|icons/icon-96x96\.png|icons/icon-144x144\.png|icons/icon-192x192\.png|icons/icon-512x512\.png|logo\.svg|favicon\.png|default-playlist\.jpg|default-avatar-account\.png|default-avatar-account-48x48\.png|default-avatar-video-channel\.png|default-avatar-video-channel-48x48\.png))$">
Header set Cache-Control "public, max-age=31536000, immutable"
</LocationMatch>
# Bypass PeerTube for performance reasons. Optional.
<LocationMatch "^/static/(thumbnails|avatars)/">
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Credentials "true"
Header set Access-Control-Allow-Headers "Retry-After"
Header set Access-Control-Allow-Methods "GET, OPTIONS"
Header set Access-Control-Allow-Headers "Range,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type"
<If "%{REQUEST_METHOD} == 'OPTIONS'">
# Preflight request can be cached 20 days
Header set Access-Control-Max-Age 1728000
Header set Content-Type "text/plain charset=UTF-8"
Header set Content-Length 0
RedirectMatch 204 ^(.*)$
</If>
# Cache response 2 hours
Header set Cache-Control "public, max-age=7200"
RewriteRule ^/static/(.*)$ /$1 [L]
</LocationMatch>
# Bypass PeerTube for performance reasons. Optional.
<LocationMatch "^/static/(webseed|redundancy|streaming-playlists)/">
# Clients usually have 4 simultaneous webseed connections, so the real limit is 3MB/s per client
SetOutputFilter RATE_LIMIT
# Increase rate limit in HLS mode, because we don't have multiple simultaneous connections
<If "%{REQUEST_URI} =~ /^(.*)-fragmented.mp4$/">
SetEnv rate-limit 5120
SetEnv rate-limit-burst 6144
</If>
<Else>
SetEnv rate-limit 832
SetEnv rate-limit-burst 1024
</Else>
<If "%{REQUEST_METHOD} == 'OPTIONS'">
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Credentials "true"
Header set Access-Control-Allow-Headers "Retry-After"
Header set Access-Control-Allow-Methods "GET, OPTIONS"
Header set Access-Control-Allow-Headers "Range,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type"
# Preflight request can be cached 20 days
Header set Access-Control-Max-Age 1728000
Header set Content-Type "text/plain charset=UTF-8"
Header set Content-Length 0
RedirectMatch 204 ^(.*)$
</If>
<If "%{REQUEST_METHOD} == 'GET'">
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Credentials "true"
Header set Access-Control-Allow-Headers "Retry-After"
Header set Access-Control-Allow-Methods "GET, OPTIONS"
Header set Access-Control-Allow-Headers "Range,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type"
# Don't spam access log file with byte range requests
SetEnvIf %{REQUEST_URI} "^(.*)$" dontlog
</If>
# Enabling the sendfile directive eliminates the step of copying the data into the buffer
# and enables direct copying data from one file descriptor to another.
# To disable if the folder is on a network filesystem like NFS or other.
EnableSendfile on
<If "%{REQUEST_URI} =~ /^\x2Fstatic\x2Fwebseed\x2F(.*)$/">
Header set Cache-control "no-cache, no-store"
</If>
RewriteRule ^/static/webseed/(.*)$ /videos/$1 [L]
RewriteRule ^/static/(.*)$ /$1 [L]
</LocationMatch>
<LocationMatch "^(/static/(webseed|web-videos|streaming-playlists)/private/)|^/download">
SetEnv rate-limit 5120
SetEnv rate-limit-burst 6144
</LocationMatch>
# Set Upgrade and Connection headers for WebSocket requests
<LocationMatch "^/(plugins/[^/]+(/[^/]+)?/ws/|socket.io/)">
Header set Upgrade "websocket"
Header set Connection "Upgrade"
</LocationMatch>
# Normal HTTP requests
ProxyPass "/" "http://backend/" flushpackets=on keepalive=on enablereuse=on upgrade=websocket
</VirtualHost>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment