Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
| docs_in_draft:docker_in_omv [2025/12/13 12:25] – [Nginx Proxy Manager] chente | docs_in_draft:docker_in_omv [2025/12/13 13:59] (current) – removed chente | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | < | ||
| - | < | ||
| - | {{ : | ||
| - | \\ | ||
| - | ---- | ||
| - | < | ||
| - | \\ | ||
| - | |||
| - | [[omv7: | ||
| - | |||
| - | ---- | ||
| - | \\ | ||
| - | \\ | ||
| - | ====== Docker in OMV 8 ====== | ||
| - | \\ | ||
| - | \\ | ||
| - | |||
| - | |||
| - | ===== Summary ===== | ||
| - | \\ | ||
| - | \\ | ||
| - | [[https:// | ||
| - | **This document establishes a method to successfully install any application on OMV using Docker.** | ||
| - | |||
| - | The [[https:// | ||
| - | |||
| - | In the case of Docker, the forum has received numerous queries about very diverse problems. Based on that forum experience, this document offers a simple method for configuring Docker that fixes the vast majority of these problems before they arise. | ||
| - | |||
| - | \\ | ||
| - | \\ | ||
| - | **Index:** | ||
| - | |||
| - | * [[omv7: | ||
| - | * [[omv7: | ||
| - | * [[omv7: | ||
| - | * [[omv7: | ||
| - | * [[omv7: | ||
| - | * [[omv7: | ||
| - | * [[omv7: | ||
| - | \\ | ||
| - | |||
| - | |||
| - | ---- | ||
| - | \\ | ||
| - | ===== What is Docker ===== | ||
| - | \\ | ||
| - | \\ | ||
| - | [[https:// | ||
| - | //" A container is a standard unit of software that packages up code and all its dependencies so the application runs quickly and reliably from one computing environment to another. A Docker container image is a lightweight, | ||
| - | |||
| - | //Container images become containers at runtime and in the case of Docker containers – images become containers when they run on Docker Engine. Available for both Linux and Windows-based applications, | ||
| - | |||
| - | \\ | ||
| - | \\ | ||
| - | ** That's all very well, but... :-) What the hell is docker? :-) ** | ||
| - | \\ | ||
| - | \\ | ||
| - | \\ | ||
| - | [[omv7: | ||
| - | That definition is very good and very professional, | ||
| - | |||
| - | Docker is a system that allows you to run an application within your server as if it were an independent and isolated system. It has its own processes, its own file system, and its own networking, all independent of the main (host) server. The container cannot access the host's file systems or network, and vice versa. This is why we say that it is isolated, and way it cannot damage your system. It is safe. | ||
| - | |||
| - | Docker is quite similar to a virtual machine, but with one key difference: a virtual machine includes a complete operating system, with its own kernel, drivers, and services. Docker, on the other hand, does **not** run a complete operating system. Instead, it uses the host's kernel and only isolates the container' | ||
| - | |||
| - | Because of this, containers consume far fewer resources and start up in a matter of seconds, although their isolation is not as deep as that of a traditional virtual machine. | ||
| - | |||
| - | **This makes containers designed for different architectures**. A container designed for Raspberry PI (ARM architecture) will not work on an Intel/AMD system (amd64 architecture) and vice versa. You should keep this in mind when choosing a container to install on your system. | ||
| - | |||
| - | Many modern containers include multiple architectures, | ||
| - | |||
| - | At this point it is good to remember that the **32-bit architecture is obsolete**, little by little 32-bit containers are disappearing. OMV 8 no longer works on 32-bit systems, so **if you were able to install OMV 8, your system is 64-bit**. When installing a container, always choose the 64-bit version. Docker will usually select the correct image automatically, | ||
| - | [[omv7: | ||
| - | |||
| - | The operation of docker is very simple. Someone on the Internet packages a system into a file we call an **image**. This image contains the necessary packages for the application we want to use to work. Docker downloads that image, installs it on our server and runs it. We already have a **container** working. | ||
| - | |||
| - | Now the creator of that image does the corresponding maintenance and publishes a new updated image. Docker can download and apply the new image if you trigger an update. Tools like docker-compose make this easy by pulling the updated image and restarting the container. This way, your container can be kept up to date. | ||
| - | |||
| - | So far so good. But now we want to configure certain information in our application, | ||
| - | |||
| - | Mapping a folder means that Docker will make a configuration such that when the container writes to the ''/ | ||
| - | |||
| - | In the same way that Docker maps folders it can also **map network ports**, we can map port 3800 that the container uses internally to any port on our server, for example 4100, the container will send data packets to port 3800 internally but Docker will that these packets be sent through port 4100 of our server. | ||
| - | [[omv7: | ||
| - | **We can also map users**. And this is important to understand. The container will work internally as //root//, but we can make that user be another user on the server, for example the user // | ||
| - | |||
| - | To define all these container configurations the **openmediavault-compose plugin uses docker-compose** for its simplicity. Using a configuration file of a few lines we define the mappings and other configurations of a container and then we execute it. | ||
| - | |||
| - | To map a user we define the PUID value, the user's identifier, and to map the group it will be the PGID value, the group' | ||
| - | |||
| - | '' | ||
| - | |||
| - | '' | ||
| - | |||
| - | The way to map a folder (**volume**) in docker-compose is something like this: | ||
| - | |||
| - | '' | ||
| - | |||
| - | That could be one of the lines in the compose file that defines a container. This line is divided into two parts. To the left of the '':'' | ||
| - | |||
| - | < | ||
| - | | ||
| - | </ | ||
| - | All that long string of numbers is the path of one of our disks on the server and inside that disk we have an appdata folder and inside we create the folderpass folder< | ||
| - | Filesystem mount paths are usually in the /srv folder and the following folder contains a uuid to uniquely identify that drive. That folder is the mount folder for that hard drive. You should never modify the permissions of that folder or use it to create a shared folder. Create a folder inside to use as a shared folder. | ||
| - | </ | ||
| - | |||
| - | From now on, every time the //root// user of the container writes to its ''/ | ||
| - | |||
| - | The advantage of all this is that the container is limited to writing to that folder. We could be unlucky enough to download an image that has harmful code inside. Or if that container was exposed to the internet and had a security hole, perhaps it could be hacked. In this case the hacker could take control of the //root// user of the container. The advantage is that that //root// user on our system is actually the // | ||
| - | |||
| - | Conclusion. **Never map the container user to the //root// user of the server**, unless it is absolutely necessary and the container developer is fully trusted. If there were a security hole in that container, your server would be at the mercy of the hacker, since they would have permissions for everything. Related to this, **never include the user running a container in the //docker// group**, this is another story but any user in the docker group can gain //root// access to the system by escalating permissions. | ||
| - | |||
| - | If you're reading this, it's probably your first time using Docker. Docker may seem complicated at first glance, but once you get over the initial learning curve, setting up and installing a container literally takes less than 30 seconds. Keep going. | ||
| - | |||
| - | ---- | ||
| - | |||
| - | \\ | ||
| - | ===== User and permission management in Docker and OMV. Improved security. ===== | ||
| - | \\ | ||
| - | \\ | ||
| - | < | ||
| - | Note | ||
| - | </ | ||
| - | You should read this even if you are an experienced Docker user but have no experience with OMV. | ||
| - | </ | ||
| - | \\ | ||
| - | [[omv7: | ||
| - | |||
| - | Docker’s security model is based on a simple principle: **a container has exactly the same permissions as the user (UID/GID) it is executed with.** | ||
| - | |||
| - | The easiest way to manage this in OMV is to create a dedicated user —for example, // | ||
| - | |||
| - | === How OMV manages users and shared folders === | ||
| - | |||
| - | In OMV, all users created through the GUI belong by default to the primary group users (GID=100). Shared folders are also created with ownership set to '' | ||
| - | |||
| - | This means that any user created from the GUI automatically has read/write access to any shared folder, since they belong to the //users// group —unless you explicitly restrict it using OMV’s permission management, which is a higher-level Samba layer. | ||
| - | |||
| - | OMV applies a Samba permission layer on top of the filesystem permissions. These are the permissions you manage from the OMV GUI. | ||
| - | * Samba permissions can restrict —but never expand— filesystem permissions. | ||
| - | * ACLs are unnecessary in 99% of cases; avoid them unless you know exactly what you're doing. | ||
| - | |||
| - | === Implications for Docker === | ||
| - | |||
| - | If you use a single user like // | ||
| - | |||
| - | This may not be desirable if one of the containers is exposed to the Internet. | ||
| - | |||
| - | === User isolation (optional, for those who need it) === | ||
| - | |||
| - | If you need maximum separation, you can create one user per container —but this only works properly if you avoid the //users// group (GID=100). To do so, you must create the users from the CLI: | ||
| - | |||
| - | '' | ||
| - | |||
| - | This creates: | ||
| - | * a user // | ||
| - | * a primary group // | ||
| - | |||
| - | When you return to the GUI, you will see the user and can manually add it to its own group. | ||
| - | This way, all files created by the container will belong to the // | ||
| - | |||
| - | === Practical conclusion === | ||
| - | |||
| - | **In this document, we will use a single //appuser// created from the GUI. This is sufficient for 99% of users.** | ||
| - | |||
| - | If your use case requires stronger isolation between containers, apply the techniques described to create users outside of GID=100 and assign them individually. | ||
| - | |||
| - | ---- | ||
| - | |||
| - | \\ | ||
| - | {{ : | ||
| - | ===== Install and configure Docker ===== | ||
| - | \\ | ||
| - | \\ | ||
| - | |||
| - | ==== 1. Installation ==== | ||
| - | |||
| - | {{ : | ||
| - | In OMV8's GUI:\\ | ||
| - | Under **SYSTEM > OMV-EXTRAS**, | ||
| - | Next, go to **SYSTEM > PLUGINS**, find and select **openmediavault-compose 8.X**, and click **INSTALL**. | ||
| - | * Installing the openmediavault-compose plugin will also install the openmediavault-sharerootfs plugin as a dependency. | ||
| - | \\ | ||
| - | < | ||
| - | Warning | ||
| - | </ | ||
| - | Do not uninstall the openmediavault-sharerootfs plugin. It is a dependency of the openmediavault-compose. Uninstalling openmediavault-sharerootfs while openmediavault-compose is installed will also remove the openmediavault-compose plugin. | ||
| - | </ | ||
| - | |||
| - | ---- | ||
| - | |||
| - | ==== 2. Plugin Settings ==== | ||
| - | |||
| - | The first step is to define the folders where the different data is stored. | ||
| - | To do this, we go to **SERVICES > COMPOSE > SETTINGS**. | ||
| - | |||
| - | There are many possible NAS layouts. | ||
| - | First we will look a simple setup, and then a more advanced configuration. | ||
| - | |||
| - | < | ||
| - | </ | ||
| - | Installing OMV on a USB flash drive may seem unusual to newcomers, but you may be surprised to learn that many professional-grade servers boot directly from USB devices.< | ||
| - | This approach provides several advantages and no drawbacks:< | ||
| - | <ul> | ||
| - | < | ||
| - | < | ||
| - | < | ||
| - | < | ||
| - | < | ||
| - | < | ||
| - | </ul> | ||
| - | If your system is already installed on a disk, you can easily migrate OMV to a USB flash drive using < | ||
| - | </ | ||
| - | |||
| - | ---- | ||
| - | |||
| - | === 2.1 SIMPLE OMV NAS SYSTEM === | ||
| - | |||
| - | In this simple setup, the OMV operating system runs from a USB stick, and there is a single data drive that stores all NAS data. On this drive we will configure Docker and all related folders. | ||
| - | |||
| - | The following diagram shows a schematic example of this layout: | ||
| - | |||
| - | {{ : | ||
| - | |||
| - | In this case, all required folders are located on the same drive, which makes the configuration very straightforward. | ||
| - | All folders will live under the mount point of that drive, for example: ''/ | ||
| - | |||
| - | Create these shared folders from the OMV GUI, then follow the explanations in section 2.3. | ||
| - | Just keep in mind that, in this simple scenario, all paths will be inside the same mount folder—for example: | ||
| - | |||
| - | * ''/ | ||
| - | * ''/ | ||
| - | * ... | ||
| - | Since there is only one data drive, everything lives under the same location. | ||
| - | |||
| - | ---- | ||
| - | |||
| - | === 2.2 ADVANCED OMV NAS SYSTEM === | ||
| - | |||
| - | In more advanced setups, your system may look similar to the following example. | ||
| - | |||
| - | The diagram below represents a typical OMV NAS layout. From this point onward, all explanations in the document will be based on this example system. Your own system will probably differ — simply adapt the configuration logic to match your real setup. | ||
| - | * The OMV operating system is installed on a USB flash drive. | ||
| - | * A mergerfs pool composed of three hard drives stores users’ large NAS data. | ||
| - | * A separate hard drive stores NAS backup data. | ||
| - | * A high-speed NVMe drive is used for Docker data. | ||
| - | |||
| - | On the right side, you can see how the plugin’s SETTINGS tab may look after applying this configuration. If your system is simpler or more complex, adjust the folder paths accordingly. | ||
| - | {{ : | ||
| - | |||
| - | ---- | ||
| - | |||
| - | === 2.3 CONFIGURATION === | ||
| - | |||
| - | In any case, the main recommendation here is to **keep Docker data separate from the OMV operating system**. | ||
| - | |||
| - | **You can name these folders however you prefer.** In this document we use the names shown in the diagrams for clarity. The example folders are: | ||
| - | * '' | ||
| - | * '' | ||
| - | * '' | ||
| - | * '' | ||
| - | (These names match the diagrams in this document. You can create the shared folder with any name you prefer; the plugin will work the same.) | ||
| - | |||
| - | We will review them one by one below. | ||
| - | |||
| - | < | ||
| - | </ | ||
| - | < | ||
| - | <ul> | ||
| - | < | ||
| - | < | ||
| - | < | ||
| - | < | ||
| - | < | ||
| - | </ul> | ||
| - | </ | ||
| - | |||
| - | \\ | ||
| - | < | ||
| - | </ | ||
| - | < | ||
| - | Required size depends on the number and type of containers. A sensible minimum is **60–100 GB**. If you run media servers (Jellyfin, Plex) with very large libraries, consider **250–500 GB** or more. Nextcloud can also require significant storage depending on your usage. | ||
| - | </ | ||
| - | |||
| - | \\ | ||
| - | < | ||
| - | </ | ||
| - | If your NAS already contains data, you probably already have a data folder (it may use a different name). Select that folder in the plugin settings if appropriate. | ||
| - | </ | ||
| - | |||
| - | \\ | ||
| - | == 2.3.1 appdata folder == | ||
| - | '' | ||
| - | |||
| - | (This name matches the diagrams in this document. You can create the shared folder with any name you prefer; the plugin will work the same.) | ||
| - | \\ | ||
| - | * WHAT IS APPDATA FOLDER: | ||
| - | * The plugin creates the //appdata// folder to store copies of the compose files it generates (both the .yml file and the .env file). These copies act as backups — do not edit them manually (always use the plugin GUI). | ||
| - | * The plugin also generates a global.env file in the appdata root. Do not edit this file manually — it is automatically overwritten. | ||
| - | * The procedure expected by the plugin would be to create a second folder in which to store persistent container data. | ||
| - | * However, many users — including myself — also use this folder to store persistent container data. It works perfectly //as long as you create a dedicated subfolder// inside each container folder. | ||
| - | * This is important because the plugin sets special permissions on every container directory it creates. If you mount a Docker volume directly into one of those folders, Docker may change the permissions and break the container or the plugin. Creating a subfolder prevents this and keeps everything safe. | ||
| - | * If you prefer to separate the persistent data into another folder, you can do so without any problem. In this document we will place persistent data in subfolders within // | ||
| - | *...< | ||
| - | </ | ||
| - | Each container is defined by two files: the < | ||
| - | </ | ||
| - | \\ | ||
| - | * HOW TO CONFIGURE THE APPDATA FOLDER: | ||
| - | * In the plugin’s SETTINGS → COMPOSE FILES section, click the **+** button next to the SHARED FOLDER field to create a new shared folder, or select an existing one if you already have it. | ||
| - | * If creating a new folder: | ||
| - | * NAME: < | ||
| - | * FILE SYSTEM: choose the SSD/NVMe or drive you want to use | ||
| - | * Click < | ||
| - | * Once selected, click **SAVE** in the plugin settings to apply the choice. | ||
| - | |||
| - | *...< | ||
| - | </ | ||
| - | This folder will store the persistent data of each container. Example for Jellyfin config:< | ||
| - | < | ||
| - | When the container starts, Docker will create missing subfolders (for example, < | ||
| - | Don't worry for now, we'll see it with examples later. | ||
| - | </ | ||
| - | *...< | ||
| - | Warning | ||
| - | </ | ||
| - | Always create a subfolder inside each container directory in < | ||
| - | ❌ <b>Do NOT do this:</ | ||
| - | / | ||
| - | → Docker writes directly inside < | ||
| - | ✔️ <b>Do this instead:</ | ||
| - | / | ||
| - | → Keeps data isolated and preserves the plugin’s permissions. | ||
| - | </ | ||
| - | *...< | ||
| - | </ | ||
| - | The compose plugin supports < | ||
| - | |||
| - | Example for Jellyfin:< | ||
| - | <b>- ./ | ||
| - | This creates:< | ||
| - | < | ||
| - | |||
| - | The plugin also supports < | ||
| - | You can create them with the < | ||
| - | Both systems (relative paths and symlinks) can be combined. | ||
| - | </ | ||
| - | |||
| - | \\ | ||
| - | == 2.3.2 data folder == | ||
| - | '' | ||
| - | |||
| - | (This name matches the diagrams in this document. You can create the shared folder with any name you prefer; the plugin will work the same.) | ||
| - | \\ | ||
| - | * WHAT IS DATA FOLDER: | ||
| - | * The data folder is basically a shortcut to a shared folder that can be used in compose files to define the location of a container volume. | ||
| - | * When a container is started, the '' | ||
| - | * You must configure this folder if you plan to use the plugin’s example compose files, as they rely on this variable. | ||
| - | * You can choose any shared folder for this purpose; it does not need to be named " | ||
| - | \\ | ||
| - | * HOW TO CONFIGURE THE DATA FOLDER: | ||
| - | * In the plugin configuration, | ||
| - | * Click SAVE. | ||
| - | |||
| - | \\ | ||
| - | == 2.3.3 backup_compose folder == | ||
| - | '' | ||
| - | |||
| - | (This name matches the diagrams in this document. You can create the shared folder with any name you prefer; the plugin will work the same.) | ||
| - | \\ | ||
| - | * WHAT IS BACKUP_COMPOSE FOLDER: | ||
| - | * The compose plugin allows you to schedule automatic backups of each container’s persistent data. | ||
| - | * All scheduled backups created by the plugin are stored in this folder. | ||
| - | \\ | ||
| - | * HOW TO CONFIGURE THE BACKUP_COMPOSE FOLDER: | ||
| - | * Create the // | ||
| - | *...< | ||
| - | </ | ||
| - | In the system diagram of this document, the < | ||
| - | The plugin’s scheduled backup function is designed to produce a consistent and up-to-date copy of your persistent data by temporarily stopping the containers during the backup and starting them again afterward. Since each backup overwrites the previous one, this folder is ideal for use together with a separate backup application, | ||
| - | If you prefer, you can place this folder directly on your backup drive instead — both approaches are valid. | ||
| - | </ | ||
| - | |||
| - | \\ | ||
| - | == 2.3.4 docker folder == | ||
| - | '' | ||
| - | |||
| - | (This name matches the diagrams in this document. You can create the shared folder with any name you prefer; the plugin will work the same.) | ||
| - | \\ | ||
| - | * WHAT IS DOCKER FOLDER: | ||
| - | * This folder contains Docker’s internal data: downloaded images, layer data, and various runtime metadata required for Docker to operate. | ||
| - | * Under normal circumstances, | ||
| - | * However, it is strongly recommended to **keep this folder off the root filesystem** (/) to avoid filling up the OS drive and to prevent performance issues. | ||
| - | * The compose plugin allows you to relocate this folder easily. In the plugin settings, under the DOCKER section, set the DOCKER STORAGE field to the new path. By default, Docker uses / | ||
| - | * When defining this path, always use the **full absolute path**. Avoid symlinks — they can cause unexpected issues with Docker. | ||
| - | \\ | ||
| - | * HOW TO CONFIGURE THE DOCKER FOLDER: | ||
| - | * Create a shared folder named //docker// in the OMV GUI. | ||
| - | * In the Compose plugin settings, under the **DOCKER** section, select the shared folder you created and press **SAVE**. | ||
| - | * The field on the left will automatically be filled with the absolute path to this shared folder. | ||
| - | *...< | ||
| - | Warning | ||
| - | </ | ||
| - | < | ||
| - | If you need to place it on < | ||
| - | < | ||
| - | Do not place the Docker folder in a < | ||
| - | If the only storage available is inside a mergerfs pool, you may: | ||
| - | - Create the Docker folder directly on a specific drive that belongs to the pool instead of inside the pool, and configure the plugin using the absolute path of that drive. | ||
| - | - Avoid using mergerfs rebalance on that pool, as it may move Docker’s files to another drive and break Docker. | ||
| - | </ | ||
| - | *...< | ||
| - | </ | ||
| - | You can < | ||
| - | This is required, for example, to configure an NVIDIA GPU driver or to set a custom storage driver for certain filesystems.< | ||
| - | If you need to customize this file, simply < | ||
| - | </ | ||
| - | |||
| - | ---- | ||
| - | |||
| - | === 3. Create appuser === | ||
| - | |||
| - | If you read the introduction, | ||
| - | |||
| - | If you are happy with this user for some or all containers, proceed; otherwise, customize it as explained earlier. | ||
| - | |||
| - | {{ : | ||
| - | * In the OMV GUI create a user called // | ||
| - | * Add //appuser// to the groups you need. | ||
| - | * For example, if you plan to use hardware transcoding with an Intel GPU, add this user to the '' | ||
| - | * ...< | ||
| - | Warning | ||
| - | </ | ||
| - | Do not add < | ||
| - | </ | ||
| - | * Edit // | ||
| - | * Give write access to //appdata// (for persistent container configuration). | ||
| - | * Give access only to the folders required as container volumes (e.g., ''/ | ||
| - | * ...< | ||
| - | </ | ||
| - | <br> | ||
| - | To create the < | ||
| - | <ul> | ||
| - | < | ||
| - | < | ||
| - | < | ||
| - | < | ||
| - | < | ||
| - | </ul> | ||
| - | To assign permissions to < | ||
| - | <ul> | ||
| - | < | ||
| - | < | ||
| - | </ | ||
| - | </ | ||
| - | * Open the UID and GID columns and note the values for // | ||
| - | * Example: UID=1002 GID=100 | ||
| - | * If you already have one user, //appuser// UID will be 1001; with two users, UID=1002, etc. This may vary depending on your system. | ||
| - | |||
| - | < | ||
| - | Warning | ||
| - | </ | ||
| - | Except in very controlled special cases, < | ||
| - | Doing so gives the container unrestricted access to your system. Consider carefully what the container is capable of doing before assigning elevated privileges. | ||
| - | </ | ||
| - | |||
| - | ---- | ||
| - | |||
| - | \\ | ||
| - | {{ : | ||
| - | ===== Configuring a container step by step (Jellyfin) ===== | ||
| - | \\ | ||
| - | \\ | ||
| - | ==== 1. Choose a container ==== | ||
| - | \\ | ||
| - | [[https:// | ||
| - | * On [[https:// | ||
| - | * Try to choose containers from reputable publishers ([[https:// | ||
| - | * Check that the container is compatible with your server' | ||
| - | * When choosing one, read the publisher' | ||
| - | [[https:// | ||
| - | * The plugin includes examples that you can install directly. | ||
| - | * As an example we are going to install [[https:// | ||
| - | *...< | ||
| - | Note | ||
| - | </ | ||
| - | If you have configured folders in the plugin' | ||
| - | </ | ||
| - | * Go to SERVICES > COMPOSE > FILES and click ADD button, then click ADD FROM EXAMPLE button. | ||
| - | * Click on the EXAMPLE field and and select the **jellyfin** file from the list. | ||
| - | * In the NAMEame field you can simply write // | ||
| - | * In the DESCRIPTION field you can write something to identify it as //Media server//. | ||
| - | * Press SAVE. | ||
| - | * You will now see a line with the compose file you just added, called // | ||
| - | < | ||
| - | Beginners Info | ||
| - | </ | ||
| - | Some containers do not provide a compose file. They can be run from the CLI using a docker command. The plugin uses docker-compose for easy setup, but you still need the compose file. If you can't find it, you can generate one using < | ||
| - | </ | ||
| - | [[https:// | ||
| - | < | ||
| - | # Date: 2025-06-01 | ||
| - | # https:// | ||
| - | # https:// | ||
| - | services: | ||
| - | jellyfin: | ||
| - | image: lscr.io/ | ||
| - | container_name: | ||
| - | environment: | ||
| - | - PUID=1000 | ||
| - | - PGID=100 | ||
| - | - TZ=Etc/UTC | ||
| - | - JELLYFIN_PublishedServerUrl=192.168.0.5 #optional | ||
| - | volumes: | ||
| - | - CHANGE_TO_COMPOSE_DATA_PATH/ | ||
| - | - CHANGE_TO_COMPOSE_DATA_PATH/ | ||
| - | - CHANGE_TO_COMPOSE_DATA_PATH/ | ||
| - | ports: | ||
| - | - 8096:8096 | ||
| - | - 8920:8920 #optional | ||
| - | - 7359: | ||
| - | - 1900: | ||
| - | restart: unless-stopped | ||
| - | |||
| - | </ | ||
| - | < | ||
| - | </ | ||
| - | Verify on the official page that this compose file has not changed before installing it | ||
| - | </ | ||
| - | \\ | ||
| - | < | ||
| - | Beginners Info | ||
| - | </ | ||
| - | < | ||
| - | A compose file is a YAML file that defines the configuration that Docker will apply to the downloaded image to create the container.< | ||
| - | The parts of this compose file for Jellyfin are as follows:< | ||
| - | <ul> | ||
| - | < | ||
| - | < | ||
| - | < | ||
| - | < | ||
| - | < | ||
| - | < | ||
| - | < | ||
| - | < | ||
| - | </ | ||
| - | </ | ||
| - | |||
| - | ---- | ||
| - | |||
| - | ==== 2. Customize the compose file ==== | ||
| - | \\ | ||
| - | The next step is to adapt the container configuration so that it works correctly on our system. We will go through this process step by step. | ||
| - | |||
| - | The first few lines of each composition file typically contain a link to the container developer' | ||
| - | |||
| - | < | ||
| - | Note | ||
| - | </ | ||
| - | < | ||
| - | |||
| - | Older versions of this document relied heavily on global variables to manage:< | ||
| - | <ul> | ||
| - | < | ||
| - | < | ||
| - | < | ||
| - | </ul> | ||
| - | < | ||
| - | The Compose plugin now supports automatic substitutions directly in the compose file. | ||
| - | <ul> | ||
| - | < | ||
| - | < | ||
| - | < | ||
| - | < | ||
| - | </ul> | ||
| - | This makes compose files simpler, cleaner, and easier to share.< | ||
| - | </ | ||
| - | |||
| - | Following the system example used in the previous section of this document, we will customize this compose file as follows: | ||
| - | \\ | ||
| - | < | ||
| - | # Date: 2025-06-01 | ||
| - | # https:// | ||
| - | # https:// | ||
| - | services: | ||
| - | jellyfin: | ||
| - | image: lscr.io/ | ||
| - | container_name: | ||
| - | environment: | ||
| - | - PUID=${{ uid:" | ||
| - | - PGID=${{ gid:" | ||
| - | - TZ=${{ tz }} < | ||
| - | #- JELLYFIN_PublishedServerUrl=192.168.0.5 | ||
| - | volumes: | ||
| - | - ${{ sf:" | ||
| - | - ${{ sf:" | ||
| - | devices: | ||
| - | - / | ||
| - | ports: | ||
| - | - 8096: | ||
| - | restart: unless-stopped | ||
| - | |||
| - | </ | ||
| - | |||
| - | ---- | ||
| - | |||
| - | < | ||
| - | </ | ||
| - | < | ||
| - | This file is in Yaml format, < | ||
| - | If you do not respect the indentations, | ||
| - | Whenever you ask for help on the forum, < | ||
| - | </ | ||
| - | |||
| - | === Environment === | ||
| - | {{ : | ||
| - | * < | ||
| - | * PUID and PGID correspond to the UID and GID of the user who will manage the container. | ||
| - | * In our case we want this user to be // | ||
| - | * < | ||
| - | PUID=${{ uid:" | ||
| - | PGID=${{ gid:" | ||
| - | </ | ||
| - | * To verify these values: | ||
| - | * In the OMV GUI, go to Users → Users, | ||
| - | * click the icon on the top-right to show the UID and GID columns. | ||
| - | * The values for //appuser// will appear there. | ||
| - | * These substitutions eliminate the need to manually copy numbers such as UID=1002 or GID=100. The plugin reads them automatically from the system. What will actually be executed in our case is: | ||
| - | * < | ||
| - | PUID=1000 | ||
| - | PGID=100 | ||
| - | </ | ||
| - | * < | ||
| - | * This line defines the time zone inside the container: | ||
| - | * < | ||
| - | TZ=${{ tz }} | ||
| - | </ | ||
| - | * The value is resolved automatically from the system time zone. | ||
| - | * To check the configured time zone: | ||
| - | * OMV GUI → System → Date & Time, look at the Time Zone field. | ||
| - | * Or in a terminal: '' | ||
| - | * What will actually be executed in the case of a server configured, for example, in Spain, is: | ||
| - | * < | ||
| - | TZ=Europe/ | ||
| - | </ | ||
| - | * If you prefer to use '' | ||
| - | * < | ||
| - | * According to the Linuxserver.io documentation, | ||
| - | * In our example it is not required, so it is commented out with # so that Docker ignores it. | ||
| - | * If you need it: | ||
| - | * Remove the ''#'' | ||
| - | * Replace the IP address with the real IP of your OMV server. Example: | ||
| - | * < | ||
| - | - JELLYFIN_PublishedServerUrl=192.168.1.100 | ||
| - | </ | ||
| - | === Volumes === | ||
| - | |||
| - | * < | ||
| - | * In the VOLUMES section we map folders between the host system and the container. This is how persistent data and media files are made available to the container. | ||
| - | * The user //appuser// must have: | ||
| - | * read and write permissions on the //appdata// folder | ||
| - | * at least read permissions on the media folders | ||
| - | * If these permissions are incorrect, the container will fail to start or will behave unexpectedly. | ||
| - | * ...< | ||
| - | Beginners Info | ||
| - | </ | ||
| - | < | ||
| - | On the left: the folder on the host< | ||
| - | On the right: the folder inside the container< | ||
| - | </ | ||
| - | * ...< | ||
| - | </ | ||
| - | < | ||
| - | You can use relative paths in compose files. For example:< | ||
| - | <b>- ./ | ||
| - | This will create the folder:< | ||
| - | < | ||
| - | on the host.< | ||
| - | This approach is useful for simple setups, but when working with OMV shared folders, using shared folder substitutions is usually clearer and safer.< | ||
| - | </ | ||
| - | * **Mapping the Jellyfin configuration folder** | ||
| - | * In the first volume line we map the ///config// folder of the Jellyfin container to a folder on the host: | ||
| - | * < | ||
| - | * The /config folder inside the container stores: | ||
| - | * Jellyfin configuration files | ||
| - | * the database | ||
| - | * users and passwords | ||
| - | * plugins | ||
| - | * metadata and cache files | ||
| - | * We place this folder inside the //appdata// shared folder, which should be located on a **fast disk** (SSD if possible). | ||
| - | * This significantly improves Jellyfin performance when loading covers, metadata, and library information. | ||
| - | * ...< | ||
| - | Beginners Info | ||
| - | </ | ||
| - | < | ||
| - | This folder contains the persistent data of the container.< | ||
| - | If you ever need to reset Jellyfin completely:< | ||
| - | 1. Stop the container< | ||
| - | 2. Delete this folder on the host< | ||
| - | 3. Start the container again< | ||
| - | Jellyfin will start in its initial state, ready to be configured from scratch.< | ||
| - | </ | ||
| - | * **Mapping media folders** | ||
| - | * In the second volume line we map the folder that contains our media files: | ||
| - | * < | ||
| - | * On the left: | ||
| - | * < | ||
| - | * ...< | ||
| - | Note | ||
| - | </ | ||
| - | < | ||
| - | Instead of mapping a dedicated media shared folder, you may also map a subfolder inside a larger shared folder:< | ||
| - | - ${{ sf:" | ||
| - | This approach is common when using mergerfs or when grouping multiple data types under a single shared folder.< | ||
| - | </ | ||
| - | * On the right: | ||
| - | * ///media// is the path that Jellyfin will see inside the container | ||
| - | * Using < | ||
| - | * ...< | ||
| - | Note | ||
| - | </ | ||
| - | < | ||
| - | In Jellyfin, libraries are configured < | ||
| - | It is not mandatory to map movies, series, photos, etc. separately.< | ||
| - | By mapping a single volume: /media Jellyfin can later access:< | ||
| - | / | ||
| - | / | ||
| - | / | ||
| - | etc.< | ||
| - | This keeps the compose file simple and flexible.< | ||
| - | </ | ||
| - | * **Additional volumes** | ||
| - | * If you have shared folders on other hard drives that you need the container to see, you can add as many volumes as you need in this section. | ||
| - | |||
| - | === Devices === | ||
| - | |||
| - | * < | ||
| - | * In the DEVICES section we can mount existing devices from the host inside the container. | ||
| - | * This step is optional. Configure it only if you need [[https:// | ||
| - | * As an example, in this case we will assume that we want to use Hardware Acceleration in Jellyfin and that the server processor is Intel and has an integrated GPU with [[https:// | ||
| - | * To mount the video device we simply add the '' | ||
| - | * When the container looks for the ''/ | ||
| - | * To grant //appuser// permissions to use this device we include it in the //render// and //video// groups. That will be enough to access the device and use it. | ||
| - | |||
| - | === Ports === | ||
| - | |||
| - | * < | ||
| - | * In the PORTS section we map the ports for the application to communicate with the outside. | ||
| - | * The process and syntax are the same as in the other sections of the compose file. | ||
| - | * If we want, we can change the port that we will use in our system to access jellyfin, or keep it the same. | ||
| - | * In this case we keep the same port, so we write '' | ||
| - | * If we wanted to change the port to 8888, for example, we would write '' | ||
| - | * If you need information about available ports you can check this forum post. [[https:// | ||
| - | * ...< | ||
| - | Beginners Info | ||
| - | </ | ||
| - | You should always make sure that the port mapped on the host is free.< | ||
| - | There are special cases where the container needs port 80 and/or port 443, with Nginx Proxy Manager. OMV uses those ports to access the GUI. You can change them in System Workbench.< | ||
| - | Another special case is pihole, which needs port 53. OMV uses port 53 and we cannot occupy it, so in this case it can be solved with a VLAN. There is a procedure in the openmediavault-compose plugin document on this wiki. | ||
| - | </ | ||
| - | |||
| - | When you run that container, the plugin will perform the substitutions and execute the following: | ||
| - | |||
| - | < | ||
| - | services: | ||
| - | jellyfin: | ||
| - | image: lscr.io/ | ||
| - | container_name: | ||
| - | environment: | ||
| - | - PUID=1000 | ||
| - | - PGID=100 | ||
| - | - TZ=Europe/ | ||
| - | volumes: | ||
| - | - / | ||
| - | - / | ||
| - | devices: | ||
| - | - / | ||
| - | ports: | ||
| - | - 8096:8096 | ||
| - | restart: unless-stopped | ||
| - | |||
| - | </ | ||
| - | |||
| - | If you don't want to use automatic substitutions, | ||
| - | |||
| - | \\ | ||
| - | ==== 3. Deploy the Container and Access the Application ==== | ||
| - | |||
| - | {{ : | ||
| - | * In the OMV GUI, go to SERVICES → COMPOSE → FILES. At this point, the line corresponding to the compose file should appear with a red indicator on the right side, indicating that the container is stopped. Select the compose file and click the UP button. | ||
| - | * A code box will appear showing the output of this command. In it, you will be able to see that the Jellyfin image is being downloaded, the container is being configured, and its execution is starting. Press CLOSE to close the code box. If everything went well, you should see the line corresponding to that compose file with the indicator on the right in green. | ||
| - | * If the container configuration is not correct, a red box will appear in the GUI indicating that there is an error. In that case, you can debug it by doing the following: | ||
| - | * Select the compose file and press the CHECK button. | ||
| - | * A dialog box will open analyzing the container configuration. You can usually identify the error by carefully reading the output shown there. | ||
| - | * Modify the compose file to correct the error and try again. | ||
| - | * If the container configuration is correct, you should be able to access your application by typing the IP address of your server followed by '':'' | ||
| - | * For example, if the IP address of your server is 192.168.1.100, | ||
| - | |||
| - | ---- | ||
| - | |||
| - | ==== 4. Help request on the OMV forum ==== | ||
| - | {{ : | ||
| - | * If you have reached this point and still cannot get your container to run, you can request help on the OMV forum. | ||
| - | * **Whenever you ask for help on the forum regarding a container, always post the compose file (and the global environment variables file, if you are using one) inside a code box**. | ||
| - | * To insert a code box press the **''</>'' | ||
| - | * Copy and paste the relevant code inside the code box. | ||
| - | * Make sure to hide any sensitive data, such as passwords, email addresses, or domain names. | ||
| - | * Finally, be polite and thankful when you receive help. Keep in mind that all forum members are volunteers, including the OMV and omv-extras developers. | ||
| - | |||
| - | ---- | ||
| - | |||
| - | \\ | ||
| - | {{ : | ||
| - | ===== Examples of configuration of some containers ===== | ||
| - | \\ | ||
| - | \\ | ||
| - | The variable substitutions performed by the plugin greatly simplify the configuration of containers. Below are a few examples. | ||
| - | |||
| - | In each case, the container has been configured following the system and folder layout described in this document. Adapt it to your own server configuration if it differs. | ||
| - | \\ | ||
| - | \\ | ||
| - | |||
| - | ---- | ||
| - | ==== Duplicati ==== | ||
| - | |||
| - | A useful application to create encrypted, versioned, compressed, and deduplicated backups, either locally or remotely. | ||
| - | [[https:// | ||
| - | < | ||
| - | # https:// | ||
| - | services: | ||
| - | duplicati: | ||
| - | image: lscr.io/ | ||
| - | container_name: | ||
| - | environment: | ||
| - | - PUID=${{ uid:" | ||
| - | - PGID=${{ gid:" | ||
| - | - TZ=${{ tz }} | ||
| - | #- CLI_ARGS= #optional | ||
| - | volumes: | ||
| - | - ${{ sf:" | ||
| - | - ${{ sf:" | ||
| - | - ${{ sf:" | ||
| - | - ${{ sf:" | ||
| - | ports: | ||
| - | - 8200:8200 | ||
| - | restart: unless-stopped | ||
| - | ########################### | ||
| - | # This compose file is customized according to the document: | ||
| - | # " | ||
| - | # Adapt it to your server if the configuration is different. | ||
| - | # https:// | ||
| - | ########################### | ||
| - | |||
| - | </ | ||
| - | |||
| - | ---- | ||
| - | |||
| - | ==== Syncthing ==== | ||
| - | |||
| - | An application to synchronize folders between different devices and the server, such as smartphones or PCs. | ||
| - | [[https:// | ||
| - | < | ||
| - | # https:// | ||
| - | services: | ||
| - | syncthing: | ||
| - | image: lscr.io/ | ||
| - | container_name: | ||
| - | hostname: syncthing #optional | ||
| - | environment: | ||
| - | - PUID=${{ uid:" | ||
| - | - PGID=${{ gid:" | ||
| - | - TZ=${{ tz }} | ||
| - | volumes: | ||
| - | - ${{ sf:" | ||
| - | - ${{ sf:" | ||
| - | - ${{ sf:" | ||
| - | ports: | ||
| - | - 8384:8384 | ||
| - | - 22000: | ||
| - | - 22000: | ||
| - | - 21027: | ||
| - | restart: unless-stopped | ||
| - | ########################### | ||
| - | # This compose file is customized according to the document: | ||
| - | # " | ||
| - | # Adapt it to your server if the configuration is different. | ||
| - | # https:// | ||
| - | ########################### | ||
| - | |||
| - | </ | ||
| - | |||
| - | ---- | ||
| - | |||
| - | ==== Nginx Proxy Manager ==== | ||
| - | |||
| - | This container allows you to securely publish services (for example, Jellyfin) on the Internet using Let’s Encrypt certificates. | ||
| - | |||
| - | It provides a very intuitive web-based administration interface. | ||
| - | |||
| - | * As a special requirement, | ||
| - | * In the OMV GUI, go to SYSTEM > WORKBENCH. | ||
| - | * Change the HTTP and HTTPS ports to unused ones. For example: | ||
| - | * HTTP: 80 → 8888 | ||
| - | * HTTPS: 443 → 8443 | ||
| - | * Apply the changes. | ||
| - | * After doing this, you will need to specify the new port in your browser to access the OMV GUI. Example: %%http:// | ||
| - | < | ||
| - | </ | ||
| - | NPM requires ports 80 and 443 on the router to validate Let's Encrypt certificates.< | ||
| - | There are two possible approaches:< | ||
| - | <b>1. Free ports 80 and 443 on the server</ | ||
| - | This is done by changing the OMV GUI ports as described above.< | ||
| - | This is the simplest and recommended option.< | ||
| - | <b>2. Use port forwarding on the router</ | ||
| - | If you prefer to keep OMV using ports 80 and 443, you can forward different external ports on the router to the container.< | ||
| - | Example:< | ||
| - | Forward external port 80 → server port 30080< | ||
| - | Forward external port 443 → server port 30443< | ||
| - | In the compose file, NPM would then use:< | ||
| - | - 30080: | ||
| - | - 30443: | ||
| - | The result is the same: the container receives traffic on ports 80 and 443 internally, while OMV keeps ports 80 and 443 on the local network.< | ||
| - | </ | ||
| - | |||
| - | [[https:// | ||
| - | < | ||
| - | # https:// | ||
| - | services: | ||
| - | app: | ||
| - | image: ' | ||
| - | restart: unless-stopped | ||
| - | ports: | ||
| - | - ' | ||
| - | - ' | ||
| - | - ' | ||
| - | # Add any other Stream ports you want to expose | ||
| - | # - ' | ||
| - | environment: | ||
| - | TZ: ${{ tz }} | ||
| - | # Mysql/ | ||
| - | DB_MYSQL_HOST: | ||
| - | DB_MYSQL_PORT: | ||
| - | DB_MYSQL_USER: | ||
| - | DB_MYSQL_PASSWORD: | ||
| - | DB_MYSQL_NAME: | ||
| - | # Optional SSL (see NPM website) | ||
| - | # DB_MYSQL_SSL: | ||
| - | # DB_MYSQL_SSL_REJECT_UNAUTHORIZED: | ||
| - | # DB_MYSQL_SSL_VERIFY_IDENTITY: | ||
| - | # Uncomment this if IPv6 is not enabled on your host | ||
| - | # DISABLE_IPV6: | ||
| - | volumes: | ||
| - | - ${{ sf:" | ||
| - | - ${{ sf:" | ||
| - | depends_on: | ||
| - | - db | ||
| - | db: | ||
| - | image: ' | ||
| - | restart: unless-stopped | ||
| - | environment: | ||
| - | MYSQL_ROOT_PASSWORD: | ||
| - | MYSQL_DATABASE: | ||
| - | MYSQL_USER: ' | ||
| - | MYSQL_PASSWORD: | ||
| - | MARIADB_AUTO_UPGRADE: | ||
| - | volumes: | ||
| - | - ${{ sf:" | ||
| - | ########################### | ||
| - | # This compose file is customized according to the document: | ||
| - | # " | ||
| - | # Adapt it to your server if the configuration is different. | ||
| - | # https:// | ||
| - | ########################### | ||
| - | |||
| - | </ | ||
| - | \\ | ||
| - | To access the Nginx Proxy Manager GUI, use port 81. Example: '' | ||
| - | |||
| - | Default credentials: | ||
| - | * User: '' | ||
| - | * Password: '' | ||
| - | You will be prompted to change these credentials on first login. | ||
| - | |||
| - | ---- | ||
| - | |||
| - | ==== Nextcloud AIO (All In One) ==== | ||
| - | |||
| - | Nextcloud is a private cloud hosting system. You will be able to access the files on your server from the internet. | ||
| - | |||
| - | This container is the official version of Nextcloud AIO (All In One). It has a configuration GUI that installs and manages several containers at the same time. | ||
| - | * The official Nextcloud AIO docker container documentation is here -> [[https:// | ||
| - | * The official Nextcloud administration documentation is here -> [[https:// | ||
| - | |||
| - | Before installing Nextcloud you need to previously install a proxy, such as the one described above Nginx Proxy Manager (you can use any other proxy supported by Nextcloud AIO, check their documentation for other options). Install NPM first and configure it following these instructions: | ||
| - | |||
| - | For this container to work you will have to do the following: | ||
| - | * You will need a domain, you can buy it or get a free one, for example at [[https:// | ||
| - | * Point the domain to your router' | ||
| - | * On your router, direct ports 80 and 443 to the IP of your server. The proxy (Nginx Proxy Manager) will receive the traffic from these ports and will direct it to the Nextcloud container through port 11000 (or to another container, if the request reaches the proxy from a domain other than Nextcloud). | ||
| - | [[https:// | ||
| - | < | ||
| - | # https:// | ||
| - | # For custom configuration consult -> https:// | ||
| - | services: | ||
| - | nextcloud-aio-mastercontainer: | ||
| - | image: nextcloud/ | ||
| - | init: true | ||
| - | restart: always | ||
| - | container_name: | ||
| - | volumes: | ||
| - | - nextcloud_aio_mastercontainer:/ | ||
| - | - / | ||
| - | ports: | ||
| - | - 8080:8080 | ||
| - | environment: | ||
| - | - APACHE_PORT=11000 | ||
| - | - NEXTCLOUD_DATADIR=${PATH_TO_APPDATA}/ | ||
| - | volumes: | ||
| - | nextcloud_aio_mastercontainer: | ||
| - | name: nextcloud_aio_mastercontainer | ||
| - | ########################### | ||
| - | # This compose file is customized following the document: " | ||
| - | # Adapt it to your server if the configuration is different. | ||
| - | # https:// | ||
| - | ########################### | ||
| - | |||
| - | </ | ||
| - | \\ | ||
| - | Start the container and make the first configuration. Follow these steps from point 4 -> [[https:// | ||
| - | |||
| - | Notice that we have configured the Nextcloud data volume in the //appdata// folder. This is due to two reasons. | ||
| - | * All files that Nextcloud manages directly are synchronized in a database and Nextcloud can modify their permissions. This may prevent you from using those files from outside of Nextcloud due to permissions and would in any case affect the Nextcloud database. | ||
| - | * Nextcloud AIO provides a backup system in its GUI that specifically includes all user data. This may not be convenient if those folders are too large and you use other means to back up that data. | ||
| - | All of this can be easily overcome by using the [[https:// | ||
| - | |||
| - | < | ||
| - | Note | ||
| - | </ | ||
| - | Nextcloud AIO is a container that spawns other containers and stores them in the docker folder. The openmediavault-compose plugin backup utility does not back up data in this folder.< | ||
| - | If you want to have a backup of this container you must use the internal backup function of Nextcloud AIO. In the Nextcloud AIO GUI you must establish where this backup is saved and how often it should be done, Nextcloud AIO takes care of everything else, stopping containers, making the backup and starting containers again. | ||
| - | </ | ||
| - | |||
| - | ---- | ||
| - | |||
| - | ==== Other containers ==== | ||
| - | {{ : | ||
| - | * Look at the examples provided by the compose plugin, there are many prepared compose files. | ||
| - | * In the OMV GUI go to SERVICES > COMPOSE > FILES and press the ADD button, then press the ADD FROM EXAMPLE button. | ||
| - | |||
| - | < | ||
| - | Beginners Info | ||
| - | </ | ||
| - | Most of the example compose files will work out of the box if you run them without making any modifications. But it will probably be better to adapt them to your system configuration according to everything explained in this document. This will avoid unexpected situations. | ||
| - | </ | ||
| - | |||
| - | ---- | ||
| - | |||
| - | ==== Create your own custom container ==== | ||
| - | \\ | ||
| - | [[omv7: | ||
| - | If you can't find a container that fits what you need in the plugin' | ||
| - | |||
| - | The openmediavault-compose plugin makes it easy to create images using the Dockerfile. You can see its use here -> [[omv7: | ||
| - | |||
| - | ---- | ||
| - | |||
| - | \\ | ||
| - | {{ : | ||
| - | ===== Some basic procedures for container management ===== | ||
| - | \\ | ||
| - | \\ | ||
| - | |||
| - | ==== How to schedule container updates and/or backups ==== | ||
| - | |||
| - | [[omv7: | ||
| - | Especially useful is this feature of the plugin. You will be able to selectively schedule container updates. And you can also make backups of the containers and volumes you want on a scheduled basis. | ||
| - | |||
| - | See how to do it in the corresponding section of the plugin document in this wiki -> [[omv7: | ||
| - | |||
| - | ---- | ||
| - | |||
| - | ==== How to modify the configuration of a container ==== | ||
| - | |||
| - | If for any reason you need to modify the container configuration, | ||
| - | |||
| - | * In the OMV GUI go to SERVICES > COMPOSE > FILES, select the container row and press the DOWN button. This will stop the container. | ||
| - | * Press the EDIT button. | ||
| - | * Modify the desired parameters in the FILE box. | ||
| - | * Press SAVE button. | ||
| - | * Select the container row again and press the UP button. The container will now be running with the modified parameters. | ||
| - | |||
| - | ---- | ||
| - | |||
| - | ==== How to reset a container' | ||
| - | |||
| - | If you want to restore the container to its initial state, do the following (This will remove any configuration we have made to the container): | ||
| - | |||
| - | * In the OMV GUI go to SERVICES > COMPOSE > FILES, select the container row and press the DOWN button. This will stop the container. | ||
| - | * Delete the config folder corresponding to the container. In the example ''/ | ||
| - | * This folder contains all the configurations that we have made inside the container. | ||
| - | * When the container starts again it will recreate the files in this folder, so no configuration will exist. We can start configuring it from scratch again. | ||
| - | * In the OMV GUI go to SERVICES > COMPOSE > FILES, select the container row and press the UP button. This will start the container. | ||
| - | |||
| - | ---- | ||
| - | |||
| - | ==== Other procedures ==== | ||
| - | |||
| - | [[omv7: | ||
| - | \\ | ||
| - | You can find several useful procedures in the corresponding section of the openmediavault-compose plugin document. Among them you will find a procedure to configure a vlan that will allow you to install **pihole** or **adguard**. -> [[omv7: | ||
| - | |||
| - | ---- | ||
| - | |||
| - | \\ | ||
| - | {{ : | ||
| - | ===== The whys ===== | ||
| - | \\ | ||
| - | \\ | ||
| - | |||
| - | === Why use global environment variables === | ||
| - | |||
| - | [[omv7: | ||
| - | * If you change a path or any other variable that affects multiple containers, it is enough to vary this value in the global environment variables file. The value will change automatically in all containers. Useful if you change a data drive, or if you reinstall OMV and change routes, for example. | ||
| - | * It is integrated into the plugin, it is enough to press a button to access the file to directly introduce the variables without doing anything else. | ||
| - | * They allow us to define a value once and all the containers that we create will use this value automatically. | ||
| - | * Useful to define routes with UUID, it is only necessary to enter it once and we will have it available to use in each container. | ||
| - | * Useful to reuse containers if we perform a reinstallation of OMV. We just need to update the values of these variables and the containers will continue to work just like before. | ||
| - | * Avoid using symbolic links if you don't need them for another reason. Despite that you could still combine the two systems if you need to. | ||
| - | |||
| - | ---- | ||
| - | |||
| - | === Why use symlinks === | ||
| - | |||
| - | [[omv7: | ||
| - | * It is integrated into OMV thanks to the [[omv7: | ||
| - | * When working with container configuration yaml files, we will likely need to copy the mount paths from our file system and they will likely be paths with UUIDs. These routes are very long and difficult to manage. | ||
| - | * A symlink is a shortcut to the folder we need. This is useful to avoid copying and pasting long flowing paths. | ||
| - | * Makes it easy to quickly change a folder path across all containers without modifying them one by one. Simply modify a symbolic link and all containers will be up to date. | ||
| - | * The use of symbolic links is not mandatory, the goal is ease of use. If you prefer to use full paths, you can skip this point. You can alternatively use the global environment variables file provided by the plugin or combine both. | ||
| - | |||
| - | ---- | ||
| - | |||
| - | === Why use docker-compose === | ||
| - | |||
| - | [[https:// | ||
| - | * It is integrated into OMV thanks to the openmediavault-compose plugin | ||
| - | * It is easy to implement, manage, edit, configure... | ||
| - | * Most docker container publishers offer a ready stack for docker-compose in their documentation. | ||
| - | * Sometimes a container publisher does not provide a stack for docker-compose. In that case you can generate it yourself with a little experience. There are also tools to do it automatically online like this one. [[https:// | ||
| - | * If you already have a working container you can generate the stack automatically from the openmediavault-compose plugin with [[omv7: | ||
| - | |||
| - | ---- | ||
| - | |||
| - | === Why use openmediavault-compose === | ||
| - | |||
| - | [[omv7: | ||
| - | * openmediavault-compose | ||
| - | * It covers all the needs of the vast majority of OMV users to use docker. | ||
| - | * It is integrated into the OMV GUI and into the system. | ||
| - | * It is automatically updated along with all other system updates. | ||
| - | * Makes it easy to manage and store container composition files. | ||
| - | * Facilitates the automatic updating and backup of containers on a scheduled and selective basis. | ||
| - | * openmediavault plugins are under constant development and new features and fixes are added as the need arises. | ||
| - | * It has the support of the OMV forum to solve any problem. | ||
| - | |||
| - | * Portainer | ||
| - | * It is not integrated into the GUI, you have to access it through another tab and port of your browser. | ||
| - | * It is one more container, it needs manual updates periodically. | ||
| - | * It does not store the composition files, you have to do it yourself. | ||
| - | * It doesn' | ||
| - | * If you have a functional problem you will have to request assistance from the Portainer developers. | ||
| - | * Disables container management from openmediavault-compose. | ||
| - | |||
| - | ---- | ||
| - | |||
| - | === Why use 64 bits? === | ||
| - | |||
| - | [[omv7: | ||
| - | * You should use a 64-bit system if your hardware allows it, 32-bit systems have been out of use for many years now. The compatibility of many software packages is still maintained, but as time goes by they are disappearing. | ||
| - | * Docker starts to be inaccessible for 32-bit systems. Many reputable container builders are stopping releasing 32-bit versions. | ||
| - | * OMV can also cause problems on 32-bit systems with docker. | ||
| - | |||
| - | ---- | ||
| - | |||
| - | \\ | ||
| - | {{ : | ||
| - | |||
| - | |||
| - | === 4. Global environmental variables === | ||
| - | |||
| - | Global environment variables are used in the procedures described in this document. | ||
| - | |||
| - | The plugin allows you to define these variables in a **single global file**. This file is then available to **all running containers**, | ||
| - | |||
| - | This makes it easy to **define paths and user IDs** once and have them applied everywhere, ensuring consistency and simplifying maintenance. | ||
| - | |||
| - | Example global environment file: | ||
| - | {{ : | ||
| - | * Variables defined in the global variables file: | ||
| - | < | ||
| - | # THE FOLLOWING VARIABLES CAN BE USED IN ANY COMPOSE FILE | ||
| - | # THEIR VALUE WILL BE REPLACED BY THE VALUE ASSIGNED HERE | ||
| - | # YOU CAN ADD AS MANY VARIABLES AS YOU NEED | ||
| - | # | ||
| - | # | ||
| - | # Customize the PID and GID value of your appuser user. | ||
| - | # You can see it in the OMV GUI in the USERS > USERS tab | ||
| - | # | ||
| - | APPUSER_PUID=1002 | ||
| - | APPUSER_PGID=100 | ||
| - | # | ||
| - | # Customize your time zone value. | ||
| - | # You can see it in the OMV GUI in the SYSTEM > DATE & TIME tab | ||
| - | # | ||
| - | TIME_ZONE_VALUE=Europe/ | ||
| - | # | ||
| - | # In this file you can define how many paths you need for different compose files. | ||
| - | # The following are examples corresponding to the example system in the Docker on OMV document on the omv-extras wiki. | ||
| - | # Customize the values according to your system configuration. | ||
| - | # | ||
| - | PATH_TO_APPDATA=/ | ||
| - | PATH_TO_DATA=/ | ||
| - | PATH_TO_DOCUMENTS=/ | ||
| - | PATH_TO_MEDIA=/ | ||
| - | PATH_TO_MOVIES=/ | ||
| - | PATH_TO_PHOTOS=/ | ||
| - | PATH_TO_BACKUPS=/ | ||
| - | PATH_TO_DOWNLOADS=/ | ||
| - | </ | ||
| - | |||
| - | * Using these variables, you could write a compose file like this: | ||
| - | |||
| - | < | ||
| - | --- | ||
| - | services: | ||
| - | jellyfin: | ||
| - | image: lscr.io/ | ||
| - | container_name: | ||
| - | environment: | ||
| - | - PUID=${APPUSER_PUID} | ||
| - | - PGID=${APPUSER_PGID} | ||
| - | - TZ=${TIME_ZONE_VALUE} | ||
| - | volumes: | ||
| - | - ${PATH_TO_APPDATA}/ | ||
| - | - ${PATH_TO_APPDATA}/ | ||
| - | - ${PATH_TO_MEDIA}:/ | ||
| - | ports: | ||
| - | - 8096:8096 | ||
| - | restart: unless-stopped | ||
| - | |||
| - | </ | ||
| - | |||
| - | * When Docker executes the compose file, it replaces the variables with the real values: | ||
| - | |||
| - | < | ||
| - | --- | ||
| - | services: | ||
| - | jellyfin: | ||
| - | image: lscr.io/ | ||
| - | container_name: | ||
| - | environment: | ||
| - | - PUID=1002 | ||
| - | - PGID=100 | ||
| - | - TZ=Europe/ | ||
| - | volumes: | ||
| - | - / | ||
| - | - / | ||
| - | - / | ||
| - | ports: | ||
| - | - 8096:8096 | ||
| - | restart: unless-stopped | ||
| - | |||
| - | </ | ||
| - | |||
| - | Why this is useful: | ||
| - | |||
| - | * You only define paths and IDs once. | ||
| - | * Compose files never need to be modified if you move folders or reinstall OMV. | ||
| - | * All containers automatically pick up the updated values. | ||
| - | |||
| - | \\ | ||
| - | < | ||
| - | Note | ||
| - | </ | ||
| - | The plugin fully supports global environment variables, even when using its backup utility. There is no need to use symlinks. If you prefer, you can still use them, but it is optional. If you don’t want to use variables, you can write the full paths and values directly in your compose files. | ||
| - | The plugin fully supports global environment variables, even while using the plugin' | ||
| - | But if you want to use them for some reason, you can still do so.< | ||
| - | If you don't want to use environment variables, simply write the full values to the compose files without using variables. | ||
| - | </ | ||
| - | \\ | ||
| - | How to configure in the OMV GUI: | ||
| - | |||
| - | * Go to SERVICES > COMPOSE > FILES and press the EDIT GLOBAL ENVIRONEMENT FILE button. | ||
| - | * In the GLOBAL ENVIRONMENT field copy and paste the example file at the beginning of this section. | ||
| - | * Customize it with your own values. | ||
| - | * PUID and PGID -> You can see the values of user //appuser// in USERS > USERS in the UID and GID columns. See point 3 of this document. | ||
| - | * TZ -> You can see your local configuration in SYSTEM > DATE & TIME and in TIME ZONE field. | ||
| - | * APPDATA -> Find the absolute path of your //appdata// shared folder in STORAGE > SHARED FOLDERS in the ABSOLUTE PATH column. Copy by clicking the link and paste it here. | ||
| - | * Customize the values of all paths according to your system configuration. If you need to define other different paths you can also do it here in the same way as the rest of the variables. | ||
| - | * You can define other variables according to your needs, such as database passwords or any value your compose file needs. | ||
| - | |||
| - | ---- | ||
| - | ===== A Closing Note ===== | ||
| - | |||
| - | We, who support the openmediavault project, hope that you’ll find your openmediavault server to be | ||
| - | enjoyable, efficient, and easy to use.\\ | ||
| - | \\ | ||
| - | If you found this guide to be helpful, please consider a modest donation to support the | ||
| - | hosting costs of this server (OMV-Extras) and the project (Openmediavault). \\ | ||
| - | \\ | ||
| - | **OMV-Extras.org** | ||
| - | \\ | ||
| - | < | ||
| - | <form action=" | ||
| - | <input type=" | ||
| - | <input type=" | ||
| - | <input type=" | ||
| - | <img alt="" | ||
| - | </ | ||
| - | </ | ||
| - | \\ | ||
| - | \\ | ||
| - | **www.openmediavault.org** | ||
| - | \\ | ||
| - | < | ||
| - | <form action=" | ||
| - | <input name=" | ||
| - | <input name=" | ||
| - | <input style=" | ||
| - | <img loading=" | ||
| - | </ | ||
| - | </ | ||
| - | |||
| - | |||
| - | \\ | ||
| - | \\ | ||
| - | \\ | ||