{"id":349,"date":"2024-03-25T08:19:55","date_gmt":"2024-03-25T08:19:55","guid":{"rendered":"https:\/\/blog.devops955.com\/swain\/?p=349"},"modified":"2024-03-25T08:19:55","modified_gmt":"2024-03-25T08:19:55","slug":"deploy-jellyfin-in-omv-6","status":"publish","type":"post","link":"https:\/\/blog.devops955.com\/swain\/2024\/03\/25\/deploy-jellyfin-in-omv-6\/","title":{"rendered":"Setting Up Your Home NAS with OpenMediaVault Part III"},"content":{"rendered":"<h1>OMV Feature Expansion<\/h1>\n<p>Beyond providing network storage, OMV officially offers many plugins to extend its functionalities, such as installing and running <strong>Plex<\/strong> or enabling Docker to set up a home multimedia platform with <strong>Jellyfin<\/strong>. To use these features, the <strong>OMV-extra<\/strong> plugin must be installed to enable Docker and then install the respective services. Beginners need not delve into the details of what Docker is; it can be considered as a functional plugin or a configured virtual machine running on OMV. We will attempt to <strong>enable Docker<\/strong> and install Jellyfin to set up a home media platform, similar to Plex (although some Plex features require a paid subscription, hence the choice of Jellyfin).<\/p>\n<h2>Installing OMV-extra<\/h2>\n<p><strong>OMV-extra<\/strong> is a plugin for OMV. Before running Jellyfin on Docker, enable the extra plugin to use advanced features. Install by logging in via SSH or locally to the OMV backend and executing the following command:<\/p>\n<pre><code class=\"language-bash\">wget -O - https:\/\/github.com\/OpenMediaVault-Plugin-Developers\/packages\/raw\/master\/install | bash<\/code><\/pre>\n<p><img decoding=\"async\" src=\"https:\/\/blog.devops955.com\/swain\/wp-content\/uploads\/sites\/2\/2024\/03\/image-16.png\" alt=\"\" \/><\/p>\n<p>This will download necessary components and execute the installation. After completion, log into the GUI and use <code>Ctrl+Shift+R<\/code> to refresh the page.<br \/>\n<img decoding=\"async\" src=\"https:\/\/blog.devops955.com\/swain\/wp-content\/uploads\/sites\/2\/2024\/03\/image-17-1024x641.png\" alt=\"\" \/><\/p>\n<p>After reloading, you'll find an omv-extras option under the system menu. Next, install the <strong>Docker Compose<\/strong> plugin by searching for 'compose' in <strong>Plugins<\/strong>, selecting it, and installing. During this process, the <strong>sharerootfs<\/strong> plugin, which is essential for operation, will also be installed and should not be uninstalled.<br \/>\n<img decoding=\"async\" src=\"https:\/\/blog.devops955.com\/swain\/wp-content\/uploads\/sites\/2\/2024\/03\/image-23-1024x640.png\" alt=\"\" \/><\/p>\n<h2>Enabling Docker<\/h2>\n<p>After installation, check the <strong>docker repo<\/strong> in omv-extra to enable Docker, then click Apply to implement changes.<\/p>\n<p>In <strong>services<\/strong>, a new <strong>compose<\/strong> service appears, showing that Docker Compose is enabled.<br \/>\n<img decoding=\"async\" src=\"https:\/\/blog.devops955.com\/swain\/wp-content\/uploads\/sites\/2\/2024\/03\/image-24-1024x755.png\" alt=\"\" \/><\/p>\n<h2>Configuring Docker<\/h2>\n<p>First, create directories for Docker in <strong>share folder<\/strong>, named <strong>docker, appdata, and data<\/strong>, plus <strong>docker_backup<\/strong> if needed. Note down the absolute path of <strong>docker<\/strong> for later configurations.<br \/>\n<img decoding=\"async\" src=\"https:\/\/blog.devops955.com\/swain\/wp-content\/uploads\/sites\/2\/2024\/03\/image-25-1024x518.png\" alt=\"\" \/><\/p>\n<p>Configure Docker under <strong>Services - Compose - Settings<\/strong>, link the relevant directories, choose <strong>appdata for Compose Files<\/strong>, select <strong>data for Data<\/strong>, and fill in the <strong>docker path<\/strong> you created. Apply the settings afterwards.<br \/>\n<img decoding=\"async\" src=\"https:\/\/blog.devops955.com\/swain\/wp-content\/uploads\/sites\/2\/2024\/03\/image-26-1024x780.png\" alt=\"\" \/><\/p>\n<p>Next, create a <strong>Docker user<\/strong> under <strong>Users - Users<\/strong>, name it <strong>appuser<\/strong> or as you prefer, and add it to the <strong>users<\/strong> group. Record the user's <strong>UID and GID<\/strong>, typically starting from 1000; if appuser is the second user, it would be <strong>1001<\/strong>, with the user group GID at <strong>100<\/strong>. Confirm this by logging into the server backend and entering <code>cat \/etc\/passwd<\/code> to see <strong>UID:GID<\/strong>.<br \/>\n<img decoding=\"async\" src=\"https:\/\/blog.devops955.com\/swain\/wp-content\/uploads\/sites\/2\/2024\/03\/image-27.png\" alt=\"\" \/><\/p>\n<p>Now you're ready to configure Docker. Return to <strong>Services - Compose - Files<\/strong>, select <strong>Edit global environment file<\/strong> to set global variables.<br \/>\n<img decoding=\"async\" src=\"https:\/\/blog.devops955.com\/swain\/wp-content\/uploads\/sites\/2\/2024\/03\/image-28-1024x318.png\" alt=\"\" \/><\/p>\n<p>Input the following (TZ is TimeZone, check in <strong>System - Date &amp; Time<\/strong> under Time zone):<\/p>\n<pre><code class=\"language-yaml\">PUID=1001\nPGID=100\nTZ=Asia\/Hong_Kong<\/code><\/pre>\n<p>With the basics set, you're now ready to install and configure Jellyfin.<\/p>\n<h2>Installing Jellyfin<\/h2>\n<p>First, choose a Docker image from <a href=\"https:\/\/hub.docker.com\/\" title=\"Docker Hub\">Docker Hub<\/a>, like <strong>jellyfin\/jellyfin<\/strong> or <strong>linuxserver\/jellyfin<\/strong>, recommending the <strong>latest<\/strong> stable version. Back in OMV, go to <strong>Services - Compose - Files<\/strong> and click <strong>Add<\/strong> to set up, or use <strong>Add from Example<\/strong> for a quick Jellyfin setup. Example configuration as follows:<\/p>\n<pre><code class=\"language-yaml\">---\n# https:\/\/jellyfin.org\/downloads\/docker\nservices:\n  jellyfin:\n    image: jellyfin\/jellyfin:latest\n    container_name: jellyfin\n    environment:\n      - PUID=1001\n      - PGID=100\n      - TZ=Asia\/Hong_kong\n    volumes:\n      - .\/config:\/config\n      - ${DATA}\/jellyfin\/tvseries:\/data\/tvshows\n      - \/srv\/dev-disk-by-uuid-a5a771ab-4ee8-4c47-bb5b-67754baf02ce\/data\/jellyfin\/movies:\/data\/movies\n    ports:\n      - 8096:8096\n    restart: unless-stopped<\/code><\/pre>\n<blockquote>\n<p>Here, <strong>.\/config<\/strong> points to the local path, and <strong>${DATA}\/jellyfin\/tvseries<\/strong> uses the <strong>variable DATA<\/strong> corresponding to the earlier set \/data directory. You can also use the complete <strong>absolute path<\/strong>.<br \/>\nPorts are for Docker to expose services through your OMV server, defaults are used here for simplicity.<\/p>\n<\/blockquote>\n<p>After configuring, select the newly created file, <strong>check<\/strong> the configuration, and if all is correct, choose <strong>up<\/strong> to start the Docker service.<br \/>\n<img decoding=\"async\" src=\"https:\/\/blog.devops955.com\/swain\/wp-content\/uploads\/sites\/2\/2024\/03\/image-29-1024x235.png\" alt=\"\" \/><\/p>\n<p>Once the image is pulled and successfully started, access <a href=\"http:\/\/serverip:8096\">http:\/\/serverip:8096<\/a> in a browser to initialize settings.<br \/>\n<img decoding=\"async\" src=\"https:\/\/blog.devops955.com\/swain\/wp-content\/uploads\/sites\/2\/2024\/03\/image-30-1024x436.png\" alt=\"\" \/><\/p>\n<p>Further Jellyfin settings are not detailed here; refer to the official documentation for guidance.<\/p>\n<p>When adding media libraries, since Docker defaults to temporary storage, ensure data is stored outside the container in persistent storage mapped earlier (e.g., \/data\/tvshows and \/data\/movies). If there are more categories (music, photos, etc.), add configurations as needed. Accordingly, or you can place all categories in the same directory for simplicity.<br \/>\n<img decoding=\"async\" src=\"https:\/\/blog.devops955.com\/swain\/wp-content\/uploads\/sites\/2\/2024\/03\/image-36-1024x709.png\" alt=\"\" \/><\/p>\n<p>Additionally, Jellyfin functions as a standalone service, thus it requires setting up individual users. When creating users, it is not necessary to set up passwords for them if they are not to be administrators, to facilitate ease of use. However, ensure that users are granted access to different media libraries to prevent them from being unable to see any content upon entry.<br \/>\n<img decoding=\"async\" src=\"https:\/\/blog.devops955.com\/swain\/wp-content\/uploads\/sites\/2\/2024\/03\/image-37.png\" alt=\"\" \/><br \/>\n<img decoding=\"async\" src=\"https:\/\/blog.devops955.com\/swain\/wp-content\/uploads\/sites\/2\/2024\/03\/image-38-1024x644.png\" alt=\"\" \/><\/p>\n<p>Lastly, just upload the media files to the server (in the corresponding OMV directories), and then scan them in the admin console to start enjoying your media collection. Future changes or updates only require scanning individual media libraries instead of rescanning all libraries, saving significant time.<br \/>\n<img decoding=\"async\" src=\"https:\/\/blog.devops955.com\/swain\/wp-content\/uploads\/sites\/2\/2024\/03\/image-39-1024x570.png\" alt=\"\" \/><\/p>\n<blockquote>\n<p>References\uff1a<br \/>\n<a href=\"https:\/\/forum.openmediavault.org\/index.php?thread\/5549-omv-extras-org-plugin\/\" title=\"OMV Extras Plugin\">OMV Extras Plugin<\/a><br \/>\n<a href=\"https:\/\/wiki.omv-extras.org\/doku.php?id=omv6:omv6_plugins:docker_compose\" title=\"OMV6 Docker Compose\">OMV6 Docker Compose<\/a><br \/>\n<a href=\"https:\/\/wiki.omv-extras.org\/doku.php?id=omv6:docker_in_omv#preparing_and_installing_docker\" title=\"Docker in OMV\">Docker in OMV<\/a><br \/>\n<a href=\"https:\/\/forum.openmediavault.org\/index.php?thread\/44784-plex-server-installation-setup-in-omv-6\/\" title=\"Plex in OMV6\">Plex in OMV6<\/a><\/p>\n<\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>This article discusses expanding OMV&#8217;s functionalities through plugins like OMV-extra and Docker, focusing on setting up a home media platform using Jellyfin.<\/p>\n","protected":false},"author":3,"featured_media":276,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_jetpack_memberships_contains_paid_content":false},"categories":[4],"tags":[],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"https:\/\/blog.devops955.com\/swain\/wp-content\/uploads\/sites\/2\/2024\/03\/jellyfin.png","_links":{"self":[{"href":"https:\/\/blog.devops955.com\/swain\/wp-json\/wp\/v2\/posts\/349"}],"collection":[{"href":"https:\/\/blog.devops955.com\/swain\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.devops955.com\/swain\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.devops955.com\/swain\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.devops955.com\/swain\/wp-json\/wp\/v2\/comments?post=349"}],"version-history":[{"count":6,"href":"https:\/\/blog.devops955.com\/swain\/wp-json\/wp\/v2\/posts\/349\/revisions"}],"predecessor-version":[{"id":369,"href":"https:\/\/blog.devops955.com\/swain\/wp-json\/wp\/v2\/posts\/349\/revisions\/369"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.devops955.com\/swain\/wp-json\/wp\/v2\/media\/276"}],"wp:attachment":[{"href":"https:\/\/blog.devops955.com\/swain\/wp-json\/wp\/v2\/media?parent=349"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.devops955.com\/swain\/wp-json\/wp\/v2\/categories?post=349"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.devops955.com\/swain\/wp-json\/wp\/v2\/tags?post=349"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}