1 { config, pkgs, lib, ... }:
3 cfg = config.services.plex;
7 (lib.mkRemovedOptionModule [ "services" "plex" "managePlugins" ] "Please omit or define the option: `services.plex.extraPlugins' instead.")
12 enable = lib.mkEnableOption "Plex Media Server";
14 dataDir = lib.mkOption {
16 default = "/var/lib/plex";
18 The directory where Plex stores its data files.
22 openFirewall = lib.mkOption {
23 type = lib.types.bool;
26 Open ports in the firewall for the media server.
34 User account under which Plex runs.
38 group = lib.mkOption {
42 Group under which Plex runs.
46 extraPlugins = lib.mkOption {
47 type = lib.types.listOf lib.types.path;
50 A list of paths to extra plugin bundles to install in Plex's plugin
51 directory. Every time the systemd unit for Plex starts up, all of the
52 symlinks in Plex's plugin directory will be cleared and this module
53 will symlink all of the paths specified here to that directory.
55 example = lib.literalExpression ''
58 name = "Audnexus.bundle";
59 path = pkgs.fetchFromGitHub {
61 repo = "Audnexus.bundle";
63 sha256 = "sha256-IWOSz3vYL7zhdHan468xNc6C/eQ2C2BukQlaJNLXh7E=";
70 extraScanners = lib.mkOption {
71 type = lib.types.listOf lib.types.path;
74 A list of paths to extra scanners to install in Plex's scanners
77 Every time the systemd unit for Plex starts up, all of the symlinks
78 in Plex's scanners directory will be cleared and this module will
79 symlink all of the paths specified here to that directory.
81 example = lib.literalExpression ''
85 repo = "Absolute-Series-Scanner";
86 rev = "773a39f502a1204b0b0255903cee4ed02c46fde0";
87 sha256 = "4l+vpiDdC8L/EeJowUgYyB3JPNTZ1sauN8liFAcK+PY=";
93 accelerationDevices = lib.mkOption {
94 type = lib.types.listOf lib.types.str;
96 example = [ "/dev/dri/renderD128" ];
98 A list of device paths to hardware acceleration devices that Plex should
99 have access to. This is useful when transcoding media files.
100 The special value `"*"` will allow all devices.
104 package = lib.mkPackageOption pkgs "plex" {
105 extraDescription = ''
106 Plex subscribers may wish to use their own package here,
107 pointing to subscriber-only server versions.
113 config = lib.mkIf cfg.enable {
114 # Most of this is just copied from the RPM package's systemd service file.
115 systemd.services.plex = {
116 description = "Plex Media Server";
117 after = [ "network.target" ];
118 wantedBy = [ "multi-user.target" ];
125 # Run the pre-start script with full permissions (the "!" prefix) so it
126 # can create the data directory if necessary.
128 preStartScript = pkgs.writeScript "plex-run-prestart" ''
129 #!${pkgs.bash}/bin/bash
131 # Create data directory if it doesn't exist
132 if ! test -d "$PLEX_DATADIR"; then
133 echo "Creating initial Plex data directory in: $PLEX_DATADIR"
134 install -d -m 0755 -o "${cfg.user}" -g "${cfg.group}" "$PLEX_DATADIR"
138 "!${preStartScript}";
140 ExecStart = "${cfg.package}/bin/plexmediaserver";
141 KillSignal = "SIGQUIT";
142 PIDFile = "${cfg.dataDir}/Plex Media Server/plexmediaserver.pid";
143 Restart = "on-failure";
146 NoNewPrivileges = true;
148 PrivateDevices = cfg.accelerationDevices == [];
149 DeviceAllow = lib.mkIf (cfg.accelerationDevices != [] && !lib.elem "*" cfg.accelerationDevices) cfg.accelerationDevices;
150 ProtectSystem = true;
152 ProtectControlGroups = true;
153 ProtectKernelModules = true;
154 ProtectKernelTunables = true;
155 RestrictAddressFamilies = ["AF_UNIX" "AF_INET" "AF_INET6" "AF_NETLINK"];
156 # This could be made to work if the namespaces needed were known
157 # RestrictNamespaces = true;
158 RestrictRealtime = true;
159 RestrictSUIDSGID = true;
160 MemoryDenyWriteExecute = true;
161 LockPersonality = true;
165 # Configuration for our FHS userenv script
166 PLEX_DATADIR=cfg.dataDir;
167 PLEX_PLUGINS=lib.concatMapStringsSep ":" builtins.toString cfg.extraPlugins;
168 PLEX_SCANNERS=lib.concatMapStringsSep ":" builtins.toString cfg.extraScanners;
170 # The following variables should be set by the FHS userenv script:
171 # PLEX_MEDIA_SERVER_APPLICATION_SUPPORT_DIR
172 # PLEX_MEDIA_SERVER_HOME
174 # Allow access to GPU acceleration; the Plex LD_LIBRARY_PATH is added
175 # by the FHS userenv script.
176 LD_LIBRARY_PATH="/run/opengl-driver/lib";
178 PLEX_MEDIA_SERVER_MAX_PLUGIN_PROCS="6";
179 PLEX_MEDIA_SERVER_TMPDIR="/tmp";
180 PLEX_MEDIA_SERVER_USE_SYSLOG="true";
181 LC_ALL="en_US.UTF-8";
186 networking.firewall = lib.mkIf cfg.openFirewall {
187 allowedTCPPorts = [ 32400 3005 8324 32469 ];
188 allowedUDPPorts = [ 1900 5353 32410 32412 32413 32414 ];
191 users.users = lib.mkIf (cfg.user == "plex") {
194 uid = config.ids.uids.plex;
198 users.groups = lib.mkIf (cfg.group == "plex") {
200 gid = config.ids.gids.plex;