What is docker and what is it for?
Docker allows you to run programs or apps in a self contained and sandboxed container, with its own OS, while sharing the host system’s resources, and in some cases libraries and devices.
LinuxServer.io’s pre-built docker images and containers can be thought of as mini virtual machines (VM) that are much lighter and more efficient than full blown VMs, and they make installing and managing apps much easier.
How does it work?
LinuxServer.io provides pre-built docker images that can be pulled/downloaded from the docker hub (hub.docker.com). These static images contain the necessary packages and apps and are either Alpine linux or Ubuntu based. A user can pull one of these images, create a container based on the image and run it to perform the tasks. Containers are ephemeral, meaning they can be easily destroyed and recreated from the docker image. For things that are meant to be persistent, like data, “volume mounts” are used to map folders on the host to folders inside the containers. Data written to these mapped folders remain outside of the container and are preserved through container destruction and recreation.
Why should I care?
LibreELEC is a Just enough Operating System (JeOS), meaning it only contains the necessary packages and libraries for the main purpose, which is Kodi. It does not contain a package manager. If one wants to install an app that requires mono, or java, those dependencies would have to be compiled for LibreELEC (not an easy task). However, with docker, one could pull a docker image and create a container that already contains all of these dependencies, and is sandboxed from LibreELEC.
How does one create a container?
Containers can be created via various methods. The simplest is through command line. The following command creates a container for running an nginx based webserver on LibreELEC:
The “-v” is used to define mount points. The left side is the host side, and the right side is the container side. So, in the above case, /storage/nginx folder on LibreELEC can be accessed inside the container at /config.
The “-e” is used to define environment variables. Above, we tell the container to set the PUID to 65534, which means the webserver will run as user “nobody” on LibreELEC. And the group id will be set to 100, which is “users”.
The “-p” defines the ports that are mapped. Again, the left side is for host and the right is for the container. Above example maps 80 to 80, but if one wants to serve the pages on port 85 instead, they would replace the above parameter with the following: “-p 85:80” so request on port 85 in LibreELEC will be forwarded to port 80 on the container.
The last element is the name of the image on docker hub. On first run, docker will download the necessary image layers from the hub, and will extract them, which can take some time for larger images especially on slower systems. Then it will create the container named nginx. One can start the container by the command “docker start nginx” and the webserver on port 80 (or 85) should come up.
What are the LinuxServer.io repo and addons?
We know that command line is not the friendliest method especially for a media center UI. LinuxServer.io created addon wrappers to make it extremely easy for users to manage docker containers.
Simply install the LinuxServer.io repo from the LibreELEC addon repositories in Kodi’s gui, then you can install various docker addons from the LinuxServer.io repo.
Once installed, the addon wrapper automatically downloads and extracts the images, sets the default parameters and creates the container. Most addons work out of the box just fine, some may require additional settings. For instance the DuckDNS docker addon, which is for updating the IP on DuckDNS’s dynamic dns service, will only set up and start the container after the user enters their subdomain and token info in the addon settings. Most docker addons allow the user to change the settings for ports and volume mount (persistent data) locations as well as app specific settings.
How does one create containers from images LinuxServer.io does not provide addons for?
LinuxServer repo contains an addon for a docker management gui called Portainer. Portainer will let you download docker images, create containers, manage their status and remove them all through a pretty gui.
How to install each LinuxServer addon + tips & tricks
You can find links to docker hub pages of each linuxserver docker image (with detailed descriptions and setup info) on the following linked page: Linuxserver.io docker image list
Below tips are specific to the libreelec addons
The updater addon is a dependency for all linuxserver docker addons and is responsible for refreshing the docker images in the background. By doing so, it ensures that when Libreelec is restarted, the new container is created based on the latest image, but it doesn't have to download the image, potentially holding up the start process.
The addon settings also provide two clean up options. It allows the user to remove all stopped containers and all unused images, freeing up space when needed.
Once installed, portainer gui will be available at your LibreELEC box’s IP at port 9000 by default, accessible from any computer on your local network. During first visit, you will be asked to create a password for the interface. Then you’ll be asked how to connect, you should select the local endpoint option, which means you’ll be managing containers on the local LibreELEC machine.
***Important: Do not use Portainer to manage containers created by LinuxServer addons. The addons have built-in mechanisms for creating, starting and stopping containers and Portainer management will interfere with that mechanism. Use Portainer to only manage containers created within Portainer.
Here’s an example on how to create a container for LinuxServer’s Calibre OPDS Php Server (COPS) image (no addon available yet): Docker Store
We pay attention to the sample “docker create” argument listed on its docker hub page for which parameters to use.
- In Portainer, we click on “Containers” and then click on “Add container”
- We fill in the name, “cops” should suffice
- The image is the last piece of the docker create sample: linuxserver/cops (keep in mind that this is the x86 version and won’t work on arm or aarch64. The arm version is at lsioarmhf/cops and the arm version should work on both arm and aarch64)
- The next items are volumes that will be mapped. In portainer, we click on the “Volumes” tab and add a couple of new volumes. We will be entering paths, so we check the boxes for “Path”. The left side will be the path on the LibreELEC machine. It could be something like “/storage/cops” and the right side will be “/config”. Which means, when the app inside the container writes the config files under “/config” folder, they will actually be stored on the “/storage/cops” folder on LibreELEC. For the second volume, point the left side to where your books are kept, and the right side will be “/books”.
- Then we create the environment variables. In Portainer, go to the “Command” tab and add three environment variables at the bottom. First variable, TZ, will help us set the timezone. On the left, enter the variable name “TZ” and on the right, enter its value ie. “America/New_York”. Then we set the other two variables PUID and PGID. The docker hub explains that these are for setting user and group ids the container user should run as. Many linux apps don’t like to run as root and it is not considered secure. For LibreELEC, we can set the PUID to 65534 (user nobody) and PGID to 100 (users) safely.
- The last parameter we need to set is the web gui port. In Portainer, in the middle of the screen, click in map port. The container port value will be 80 (you can’t change that because the app inside the container is coded to expect incoming connections on port 80). But you can set the host port to anything you like, and docker will forward that port to port 80 inside the container. Make sure that the host port is currently not being used by anything else, otherwise the container will not start.
- Lastly, we can select the start method at the top. If you would like your container to start on boot and always run in the background, set the restart policy to “always”.
- Now that all the settings are taken care of, we can hit “Create” at the bottom. Portainer will show the gears while it downloads the image from the hub, extracts it, and then creates a container from it based on your settings. Some images can be very large and in those cases it might take a while for the download, extraction and creation. Be patient.
The settings are very straightforward. The default port is 8337 (can be changed in settings). The default music location is /storage/music and the default download location is /storage/downloads/beets
Make sure you sign up for an account first at duckdns.org and retrieve your token for your subdomains. In the settings you have to enter the subdomains and token before the container will run. You can enter multiple subdomains, comma separated, no spaces and this service will update the IP address for all subdomains listed.
Set the config and backup locations and access the web gui at port 8200 by default.
This is a relatively large image and may take a while to set up especially on slower systems. The default mapped locations are /storage/videos and /storage/tvshows which show up as /data/movies and /data/tvshows inside the container.
Once installed, you can visit the emby web gui at port 8096. Additional parameters are optional and only needed if you need to map additional volumes or pass other variables. Please use the docker command line parameter structure ie. “-v /storage/path:/data/additional”. Leave blank otherwise.
On X86_64 with an intel igpu, hardware transcoding is supported in this container.
This is not a Linuxserver maintained docker image. We only support the wrapper addon. The image is the official emby docker image (emby/embyserver).
This container is an nginx web server with php built-in. It automatically retrieves SSL certs for your domain via letsencrypt, and has fail2ban included for intrusion prevention.
There are three ways letsencrypt can validate the domain: http, tls and dns (tls method currently disabled due to a vulnerability)
If you want to validate ownership via http, then port 80 on the router's wan side has to end up at port 80 inside this container. It can however go through a different port in between. For instance port 80 on the router is forwarded to port 85 on LE. Then in the addon settings, you select 85 for the mapping so docker will map 85 on LE to 80 inside the container.
For dns validation, port mapping is not crucial.
For http validation, this container best used with a duckdns domain name. In which case, the url will be “yourcustomsubdomain.duckdns.org” and the subdomain can be “www,ftp,etc” (comma separated, no spaces).
If you own your own domain, cloudflare is recommended for dns validation. Point your nameservers to cloudflare on your registrar, and in cloudflare, set it to "dns only". The url in addon settings would be “customdomain.com”. For dns plugin, select cloudflare. Once the container is started, one has to go the addon folder, find the cloudflare.ini under "dns-conf" and enter the credentials. Then the container can be forced to restart via disabling and re-enabling the addon.
Wildcard certs are supported via dns validation only. In the subdomains field, enter "wildcard" only.
***Important: This container creates a dhparams file for security on first start. That process does extensive mathematical calculations with regards to prime numbers and is very cpu intensive. The process could take up to an hour on slow systems during which time, there won’t be a web page available. Be patient. At the end, you should be able to navigate to your custom domain and access the sample web page. All the web files are stored in the config folder which is by default under “/storage/.kodi/userdata/addon_data/docker.linuxserver.letsencrypt/config” and through smb, it can be found under “userdata/addon_data/docker.linuxserver.letsencrypt/config”. Restart the container by disabling the addon and reenabling it after making changes to the config files.
This container also has preset reverse proxy confs for other popular containers. Navigate to the addon folder and under "nginx/dns-confs" you'll see sample confs. To enable them, simply rename them to remove ".sample" from the name and restart the container. More info is provided in the container description: readme.md
The default port is 3306, which can be changed. Upon install, settings window will open and you can enter a root password. From other containers and services, use the IP address of the LE box rather than localhost or 0.0.0.0 to connect to mariadb, because docker containers are sandboxed from each other and the system.
If you would like to use this addon to host the kodi library on the same machine, in kodi’s advancedsettings.xml, use the IP address of the LE device.
Set the ports and select you device. Default device address is “/dev/dvb”, may be different in your case. Optional parameters allowed for minisatip (ie. to set up a unicable LNB). Leave blank if not needed.
Just select the web gui port in settings (default 84) and you’re good to go. All other settings are through the web gui.
Default port is 443. Select the data folder location. You can combine this with the mariadb addon (enter the box ip and port, default user is root and no password unless manually set).
You can combine this with the letsencrypt container to use as a reverse proxy and benefit from 3rd party validated ssl certs.
Basic nginx web server with php7 and self signed ssl cert. Ports 80 and 443 are forwarded. Web and configuration files go into the mapped config folder.
Supports up to 4 devices. Default gui port is 8888. Enter the device addresses and ports in the settings.
Default gui port is 83. Map locations for the picture and thumbs, as well as the config folder.
This is not a linuxserver provided docker image but we provide support for the wrapper addon. The docker image used is the official pi-hole image (diginc/pi-hole)
On first install, the settings window will open. Enter an admin password. By default, only IPv4 is enabled and the IP of the LE box is auto-detected. In the settings, you can enable IPv6 and/or override the server IPs with manually entered values.
Due to issues with the official image, the settings can only be set during first install. Changing the settings later on will have no effect unless the addon data folder is deleted.
Map the locations for movies, tv shows and a temporary transcode folder. The web gui is at port 32400. Image is quite large so it takes a little while to start the first time. Once started, register for a plex account, login, and then go to the LE box’s IP at port 32400 to set up. The internal locations for movies and tv shows mapped are “/data/movies” and /data/tvshows” respectively. By default, it installs the latest public release of plex media server and updates during start or reboot. On x86, it supports plexpass releases, just set the version parameter to “latest” for the plexpass version. You can also set it to a specific version number (ie. 184.108.40.20633-03e4cfa35) for specific builds like the DVR builds (not available for arm or aarch64).
On X86_64 with an Intel igpu, hardware transcode is supported in this container.
Default port is 8181. The internal mapped folder for the plex library location is “/logs” and select that as the library location in its gui settings.
Default port is 4242. Connect via its client and set a password during initial connection.
The web gui port is 8888 and the p2p connection port is 55555. Set the sync location in the settings.
Default port is 9001.
Set a recording location (internally /recordings). In the settings, select whether you would like to use a card or iptv. If card is selected, enter the port numbers and the card address. The version/tag setting can be “latest” or “stable-4.0.9” (options found here: tags)
Default port is 6501
Commands For Troubleshooting:
“docker ps -a” will list all existing containers with their names
“docker images” will list all downloaded and extracted docker images
“docker logs [containername]” will output the docker log
“journalctl -u [containername].service” will show the systemd log for addon containers
“systemctl status [containername].service” will show systemd status of the addon container service
Frequently Asked Questions:
I installed the addon but nothing happened:
The addons initiate the download and extraction of an image from docker hub before container creation. Depending on image size, internet speed and cpu power, this could take some time. Be patient.
Some addons require users to set custom settings in the addon settings (ie. DuckDNS requires the subdomains and token to be entered)
Make sure the web gui ports selected in the gui aren’t in use by another service. If so, the container cannot be created.
How do I stop/restart a LinuxServer addon container?
To stop, simply disable the addon (or uninstall). You can re-enable/re-install the addon to start the container again.
How do I update a LinuxServer addon container or the app inside?
LinuxServer docker images are refreshed/updated every Friday night (UTC). Linuxserver updater addon pull new images every night in the background. Once the addons or Libreelec are restarted containers will be recreated based on the latest images. So simply disable and re-enable the addon and it should update itself.
It just doesn’t work!