Plex

From NixOS Wiki
Jump to: navigation, search

Plex media server allows you to aggregate all your personal media and access it anywhere you go. Enjoy your own content on all your devices with Plex.

Basic setup

Plex is pre-packaged on NixOS already. All you need is to edit your configuration.nix. A simple configuration looks like

services.plex = {
  enable = true;
  openFirewall = true;
};

After adding this to your configuration.nix just rebuild your system.

Of course there's some more options that you can customize.

If your Plex media server is behind a router, you'll need to forward tcp port 32400 to your Plex media server.

Access Plex media server by browsing to http://lan_ip:32400/web

Plex Media Player (PMP)

Plex Media Player is the current release of Plex's media client. Plex has made PMP available to all users and it has also become compatible with Kodi.

Installation

$ nix-env -i plex-media-server

SSL Access via Nginx Revers Proxy

Because of several redirects within Plex media server it's not easy to make it accessible through SSL. Browser can complain, even if you have configured propler SSL certificates in your plex setup.

Fortunately Nginx can be used as a reverse proxy server to access Plex media server. Most of the configuration below comes from kopfpilot on the Plex forum.

# Nginx Reverse SSL Proxy
services.nginx = {
  enable = true;
  # give a name to the virtual host. It also becomes the server name.
  virtualHosts."sub.domain.tld" = {
    # Since we want a secure connection, we force SSL
    forceSSL = true;

    # http2 can more performant for streaming: https://blog.cloudflare.com/introducing-http2/
    http2 = true;

    # Provide the ssl cert and key for the vhost
    sslCertificate = "/https-cert.pem";
    sslCertificateKey = "/https-key.pem";
    extraConfig = ''

      #Some players don't reopen a socket and playback stops totally instead of resuming after an extended pause
      send_timeout 100m;

      # Why this is important: https://blog.cloudflare.com/ocsp-stapling-how-cloudflare-just-made-ssl-30/
      ssl_stapling on;
      ssl_stapling_verify on;

      ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
      ssl_prefer_server_ciphers on;
      #Intentionally not hardened for security for player support and encryption video streams has a lot of overhead with something like AES-256-GCM-SHA384.
      ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';

      # Forward real ip and host to Plex
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
      proxy_set_header Host $server_addr;
      proxy_set_header Referer $server_addr;
      proxy_set_header Origin $server_addr; 

      # Plex has A LOT of javascript, xml and html. This helps a lot, but if it causes playback issues with devices turn it off.
      gzip on;
      gzip_vary on;
      gzip_min_length 1000;
      gzip_proxied any;
      gzip_types text/plain text/css text/xml application/xml text/javascript application/x-javascript image/svg+xml;
      gzip_disable "MSIE [1-6]\.";

      # Nginx default client_max_body_size is 1MB, which breaks Camera Upload feature from the phones.
      # Increasing the limit fixes the issue. Anyhow, if 4K videos are expected to be uploaded, the size might need to be increased even more
      client_max_body_size 100M;

      # Plex headers
      proxy_set_header X-Plex-Client-Identifier $http_x_plex_client_identifier;
      proxy_set_header X-Plex-Device $http_x_plex_device;
      proxy_set_header X-Plex-Device-Name $http_x_plex_device_name;
      proxy_set_header X-Plex-Platform $http_x_plex_platform;
      proxy_set_header X-Plex-Platform-Version $http_x_plex_platform_version;
      proxy_set_header X-Plex-Product $http_x_plex_product;
      proxy_set_header X-Plex-Token $http_x_plex_token;
      proxy_set_header X-Plex-Version $http_x_plex_version;
      proxy_set_header X-Plex-Nocache $http_x_plex_nocache;
      proxy_set_header X-Plex-Provides $http_x_plex_provides;
      proxy_set_header X-Plex-Device-Vendor $http_x_plex_device_vendor;
      proxy_set_header X-Plex-Model $http_x_plex_model;

      # Websockets
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";

      # Buffering off send to the client as soon as the data is received from Plex.
      proxy_redirect off;
      proxy_buffering off;
    '';
    locations."/" = {
      proxyPass = "http://plex.domain.tld:32400/";
    };
  };
};

In order to use that, basically set the vhost name from sub.domain.tld to your actual (sub)domain name. Also point to the right sslCertificate and sslCertificateKey. Finally set the proxyPass address to where your Plex media server is.

After applying the changes, just browse to https://sub.domain.tld/web. Of course use your actual (sub)domain name.