{ config, lib, pkgs, ... }: let mpd_loc = (import ../data/aliases.nix).services.mpd; mpdweb_loc = (import ../data/aliases.nix).services.mpdweb; pjournal_loc = (import ../data/aliases.nix).services.pjournal; in { imports = [ ./orbekk-pkgs.nix ]; security.acme.acceptTerms = true; security.acme.email = "kj@orbekk.com"; networking.firewall.allowedTCPPorts = [ 80 443 ]; # I'm storing web files in /home. systemd.services.nginx.serviceConfig.ProtectHome = "read-only"; systemd.services.nginx.serviceConfig.ReadWritePaths = ["/storage/srv/kj.orbekk.com/tmp/hls/"]; services.nginx = { enable = true; package = pkgs.nginxStable.override { modules = with pkgs.nginxModules; [ dav rtmp ]; }; recommendedProxySettings = true; appendHttpConfig = '' # This is a workaround to deal with closed connections on # large downloads. proxy_buffering off; charset utf-8; tcp_nopush on; aio on; directio 512; ''; appendConfig = '' rtmp { server { listen 1935; allow publish 10.0.0.0/8; deny publish all; allow play all; chunk_size 4906; application live { live on; record off; hls on; hls_path /storage/srv/kj.orbekk.com/tmp/hls/; hls_fragment 1s; hls_playlist_length 2s; } } } ''; virtualHosts = let template = { enableACME = true; forceSSL = true; }; in { "tommvo.com" = template // { root = "/storage/srv/tommvo.com"; }; "orbekk.no" = template // { root = "/storage/srv/orbekk.com"; }; "orbekk.com" = template // { root = "/storage/srv/orbekk.com"; }; "wifi.orbekk.com" = template // { root = "/storage/srv/wifi.orbekk.com"; }; "wifi.orbekk.no" = template // { root = "/storage/srv/wifi.orbekk.com"; }; "kj.orbekk.com" = template // { root = "/home/orbekk/www-public"; locations."/" = { extraConfig = '' try_files $uri @storage; # kill cache add_header Last-Modified $date_gmt; add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0'; if_modified_since off; expires off; etag off; ''; }; locations."/hls" = { extraConfig = '' default_type application/octet-stream; # Disable cache # add_header Cache-Control no-cache; # CORS setup add_header 'Access-Control-Allow-Origin' '*' always; add_header 'Access-Control-Expose-Headers' 'Content-Length'; # allow CORS preflight requests if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Max-Age' 1728000; add_header 'Content-Type' 'text/plain charset=UTF-8'; add_header 'Content-Length' 0; return 204; } types { application/vnd.apple.mpegurl m3u8; video/mp2t ts; } root /storage/srv/kj.orbekk.com/tmp/; ''; }; locations."@storage" = { root = "/storage/srv/kj.orbekk.com"; extraConfig = '' autoindex on; ''; }; locations."/dav" = { root = "/storage/srv/kj.orbekk.com"; extraConfig = '' auth_basic webdav; # htpasswd -c /opt/secret/nginx-webdav.htpasswd dav_ext_methods PROPFIND OPTIONS; auth_basic_user_file "/opt/secret/nginx-webdav.htpasswd"; dav_methods put delete mkcol copy move; dav_access user:rw group:rw all:rw; create_full_put_path on; autoindex on; ''; }; }; "git.orbekk.com" = template // { locations."/".proxyPass = "http://localhost:11103"; }; "journal.orbekk.com" = template // { locations."/".proxyPass = "http://localhost:${toString pjournal_loc.port}"; }; }; }; }