The OwnTone container offers a hassle-free solution for deploying the OwnTone media server. By encapsulating OwnTone and its dependencies in a container, users enjoy consistent deployment across various platforms.
This approach enhances reliability, simplifies version control, and allows users to focus on using OwnTone’s media server features rather than dealing with complicated installation processes.
If you can’t wait to run OwnTone, here is a quick start procedure. It implies that you already have a running Docker or Podman installation.
-
Create a minimal structure, assuming everything is in the home directory
mkdir -p $HOME/OwnTone/{etc,media,cache}
-
Launch the container
docker run -d \ --name=OwnTone \ --network=host \ -e UID=$(id -u) \ -e GID=$(id -g) \ -v $HOME/OwnTone/etc:/etc/owntone \ -v $HOME/OwnTone/media:/srv/media \ -v $HOME/OwnTone/cache:/var/cache/owntone \ --restart unless-stopped \ docker.io/owntone/owntone:latest
The OwnTone container comes in two flavours: the production (tag latest
) and the staging (tag staging
) releases.
The staging release is designed for users who seek access to the latest features or bug fixes, providing a platform for testing and experimentation. In contrast, the production release is characterised by heightened stability, making it suitable for environments where reliability is paramount.
The deployment procedure can be described in 2 main steps.
- Setup: The creation of user and directories, and network that will be used by OwnTone.
- Running: A set of commands and alternatives to start OwnTone.
This OwnTone container needs a certain amount of parameters to be configured to work properly. Mainly, the user and group running OwnTone, the directories where the database containing the metadata and your media are located, and the network on which it is connected.
OwnTone should run with a specific user that you have to create on the host. If you don’t specify any user identifier (UID
) and group identifier (GID
) (see section Run), then the user and group with identifier 1000 will be used.
The following directories, should be set up.
- Configuration directory - contains the configuration of OwnTone (by default
/etc/owntone/
). - Media directory - contains all the media which will be available to be streamed by OwnTone (by default
/srv/media
). - Cache directory - indicates where the OwnTone database (
database.db
) is being located (by default/var/cache/owntone
).
The above mentioned directories can all be changed to fit your context.
Furthermore, you must ensure that at least the cache directory is writable by the user and group identifiers provided at startup. Depending on your configuration, the media directory might need to be writeable by the user and group identifiers provided at startup.
OwnTone needs some network access to stream the audio to the audio devices. You have two options:
A. Share the container host IP address (see Host Network Stack below), or B. Create a separate network and have OwnTone to be considered as a separate host (see Separate Network below).
In the case you simply want to use the network of the container host, then you will need to use the host
network mode.
In specific situations, it is expected to have a container to be considered as a separate "machine" on the network. Thus, you won’t have any limitation on ports you are using and therefore, you also won’t have to worry about mapping ports. It gives as well the opportunity to have multiple OwnTone instances running in the same network.
To create a new network, you can run the following command:
docker network create \
--driver macvlan \
--subnet=<subnet> \
--gateway=<gateway> \
--ip-range=<ip-range> \
-o parent=<interface> \
<name>
Where
<subnet>
The subnet of the new network.<ip-range>
The range of IPs for the new network.<gateway>
The gateway of for the new network.<interface>
The name of the physical network interface of the host.<name>
The name of the new network.
In the example below, we use the macvlan
driver attached to the physical interface enp3s0
.
It allows us to use the subnet of the router which is 192.168.0.0/24
- 192.168.0.1
to 192.168.0.254
.
Moreover, the router is configured to lease IP addresses, through DHCP, from 192.168.0.2
to 192.168.0.127
.
Thus, the range of IPs leased by the router will not overlap with the range defined by the container network.
Indeed, the new network has an IP range from 192.168.0.192
to 192.168.0.222
.
docker network create \
--driver macvlan \
--subnet=192.168.0.0/24 \
--gateway=192.168.0.1 \
--ip-range=192.168.0.192/27 \
-o parent=enp3s0 \
intnet
There are multiple ways to start the OwnTone container.
- Run Command
- Compose Command
- SystemD
The most direct way to start the OwnTone container is to use the Docker Run command.
docker run -d \
--name=<container-name> \
--network=<network>
-e UID=<uid> \
-e GID=<gid>
-v <configuration-location>:/etc/owntone \
-v <media-location>:/srv/media \
-v <database-location>:/var/cache/owntone \
--restart unless-stopped \
docker.io/owntone/owntone:<tag>
Where
<container-name>
A unique name for the container.<network>
The type of network you are choosing. It can be the name of the network (e.g.,intnet
as in the example above), or the network modehost
.<uid>
The identifier of the user that will start the OwnTone process.<gid>
The identifier of the group that is attached to the OwnTone user.<configuration-location>
The path where the configuration is stored.<media-location>
The path where the media are stored. Be sure to provide at least read access to the user running OwnTone.<database-location>
The path where the database is stored. Be sure to provide write access to the user running OwnTone.<tag>
The tag identifies which release has to be deployed. There are two meta tags:latest
for latest production release andstaging
for the latest staging release (for more information, see the section Releases)
docker run -d \
--name=OwnTone \
--network=host \
-e UID=1000 \
-e GID=1000 \
-v /etc/owntone:/etc/owntone \
-v /mnt/media:/srv/media \
-v /var/cache/owntone:/var/cache/owntone \
--restart unless-stopped \
docker.io/owntone/owntone:latest
The main difference between Run and Compose is that with Compose, you use a YAML file to configure the container instance. Instead of running the Run command above - which can be extensively long - from a command line, all the configuration is stored in a YAML file.
Hereunder, you have an example of a Compose file (owntone.yaml
).
---
version: "3.8"
services:
owntone:
image: docker.io/owntone/owntone:latest
container_name: OwnTone
network_mode: host
environment:
- UID=1000
- GID=1000
volumes:
- /etc/owntone:/etc/owntone
- /mnt/media:/srv/media
- /var/cache/owntone:/var/cache/owntone
restart: unless-stopped
docker compose -f owntone.yaml
Once you have the container running, you might want to automate the start and stop of OwnTone with your system.
If your system runs systemd, it might be useful to automate the start of OwnTone with a Unit file. You can find a list of presenting the adoption of systemd in Gnu/Linux distributions here.
Using a Podman Quadlet, makes it efficient to start your OwnTone container.
Below, an example of such a configuration file. Usually, this file (e.g., owntone.container
) should be located in the /etc/containers/systemd/
.
[Unit]
Description=OwnTone Container
[Container]
ContainerName=owntone
Image=docker.io/owntone/owntone:latest
AutoUpdate=registry
Network=host
HostName=owntone
Environment=UID=1000
Environment=GID=1000
Mount=type=bind,source=/etc/owntone,destination=/etc/owntone
Mount=type=bind,source=/mnt/media,destination=/srv/media
Mount=type=bind,source=/var/cache/owntone,destination=/var/cache/owntone
[Install]
WantedBy=multi-user.target default.target
For general instructions on how to build OwnTone, please follow the directions indicated here.
Nevertheless, if you want to create your very own version of the container image, you can use the existing existing continuous integration definitions for Azure or GitHub:
- Azure ./azure/workflows/container-image.yml
- GitHub ./github/workflows/container-image.yml
It is also possible to run the build command locally with docker build
or podman build
.
This can become handy if you have made a fork of OwnTone and want to test some new features you have implemented.
The Dockerfile can take a few build arguments:
PACKAGE_REPOSITORY
The URL of the Alpine Linux package repository. By default, the latest community stable packages are taken.REPOSITORY_URL
The URL of the source code of OwnTone. By default, the official source code repository is considered.REPOSITORY_BRANCH
The branch that will be used as the source code base.REPOSITORY_COMMIT
The commit on which the build will be based.REPOSITORY_VERSION
The version on which the build will be based.
- If both a commit (commit identifier) and a version are provided, the commit has precedence over the version.
- If none of the above (commit or version) are provided, the last commit of the specified branch is provided.
- If no branch is provided, the default
master
branch is used. - If no URL for the repository is provided, the original OwnTone repository is used.
Currently, this containerisation supports the amd64 (x86-64) and arm64 (aarch64) architectures.
If you want to use a specific architecture, you have to specify the option --platform
with docker
or podman
.
If you want to contribute to make this containerisation better, please open a work item here.