Allow splitting config, downloads and media paths via .env
Some checks failed
Check running / run (push) Has been cancelled
Some checks failed
Check running / run (push) Has been cancelled
Adds optional CONFIG_DIR, DOWNLOADS_DIR and MEDIA_DIR env variables so
users can spread configs, downloads and media across different drives
without restructuring ROOT_DIR. Each falls back to its ROOT_DIR-based
default when left empty, so existing setups keep working unchanged.
The -arr services (sonarr, radarr, lidarr, mylar3) now use a single
${DOWNLOADS_DIR}:/data parent bind with a ${MEDIA_DIR}:/data/media
overlay. This preserves TRaSH's single-/data-mount semantics inside
the container (hardlinks still work on one filesystem) while letting
the host-side media tree live wherever the user wants.
README documents the new variables, the generated folder structure,
recommended storage layouts, and the same-filesystem requirement for
hardlinks between downloads and media.
This commit is contained in:
@@ -7,21 +7,42 @@ class ContainerConfig:
|
||||
root_dir,
|
||||
timezone,
|
||||
plex_claim='',
|
||||
config_dir=None,
|
||||
downloads_dir=None,
|
||||
media_dir=None,
|
||||
):
|
||||
self.root_dir = root_dir
|
||||
self.timezone = timezone
|
||||
self.config_dir = f'{root_dir}/config'
|
||||
self.plex_claim = plex_claim
|
||||
self.movie_dir = f'{root_dir}/media/movies'
|
||||
self.tv_dir = f'{root_dir}/media/tv'
|
||||
self.music_dir = f'{root_dir}/media/music'
|
||||
self.book_dir = f'{root_dir}/media/books'
|
||||
self.comic_dir = f'{root_dir}/media/comics'
|
||||
self.torrent_dir = f'{root_dir}/data/torrents'
|
||||
self.usenet_dir = f'{root_dir}/data/usenet'
|
||||
# Allow each of config / downloads / media to be overridden independently.
|
||||
# When not provided, fall back to the ROOT_DIR-based defaults used historically.
|
||||
self.config_dir = config_dir or f'{root_dir}/config'
|
||||
self.downloads_dir = downloads_dir or f'{root_dir}/data'
|
||||
self.media_dir = media_dir or f'{root_dir}/data/media'
|
||||
self.movie_dir = f'{self.media_dir}/movies'
|
||||
self.tv_dir = f'{self.media_dir}/tv'
|
||||
self.music_dir = f'{self.media_dir}/music'
|
||||
self.book_dir = f'{self.media_dir}/books'
|
||||
self.comic_dir = f'{self.media_dir}/comics'
|
||||
self.torrent_dir = f'{self.downloads_dir}/torrents'
|
||||
self.usenet_dir = f'{self.downloads_dir}/usenet'
|
||||
self.homarr_dir = f'{root_dir}/data/homarr/appdata'
|
||||
self.UID = pwd.getpwnam(getpass.getuser()).pw_uid
|
||||
|
||||
def _arr_data_volumes(self):
|
||||
"""Volume lines for services that need the full /data tree (sonarr, radarr, lidarr, mylar3).
|
||||
|
||||
Emits a single ``${downloads_dir}:/data`` parent mount plus a ``${media_dir}:/data/media``
|
||||
overlay. The overlay is a no-op when ``media_dir`` is the default ``${downloads_dir}/media``
|
||||
(Docker just binds the same subpath) and transparently redirects ``/data/media`` when the
|
||||
user has pointed ``media_dir`` at a different location. This preserves TRaSH's single-
|
||||
``/data``-mount semantics while still allowing an independent ``MEDIA_DIR``.
|
||||
"""
|
||||
return (
|
||||
f' - {self.downloads_dir}:/data\n'
|
||||
f' - {self.media_dir}:/data/media\n'
|
||||
)
|
||||
|
||||
def plex(self):
|
||||
return (
|
||||
' plex:\n'
|
||||
@@ -35,7 +56,7 @@ class ContainerConfig:
|
||||
f' - PLEX_CLAIM={self.plex_claim}\n'
|
||||
' volumes:\n'
|
||||
f' - {self.config_dir}/plex-config:/config\n'
|
||||
f' - {self.root_dir}/data/media:/media\n'
|
||||
f' - {self.media_dir}:/media\n'
|
||||
' restart: unless-stopped\n\n'
|
||||
)
|
||||
|
||||
@@ -69,7 +90,7 @@ class ContainerConfig:
|
||||
f' - TZ={self.timezone}\n'
|
||||
' volumes:\n'
|
||||
f' - {self.config_dir}/jellyfin-config:/config\n'
|
||||
f' - {self.root_dir}/data/media:/data\n'
|
||||
f' - {self.media_dir}:/data\n'
|
||||
' ports:\n'
|
||||
' - "8096:8096"\n'
|
||||
' restart: unless-stopped\n\n'
|
||||
@@ -87,7 +108,7 @@ class ContainerConfig:
|
||||
f' - TZ={self.timezone}\n'
|
||||
' volumes:\n'
|
||||
f' - {self.config_dir}/sonarr-config:/config\n'
|
||||
f' - {self.root_dir}/data:/data\n'
|
||||
f'{self._arr_data_volumes()}'
|
||||
' ports:\n'
|
||||
' - "8989:8989"\n'
|
||||
' restart: unless-stopped\n\n'
|
||||
@@ -105,7 +126,7 @@ class ContainerConfig:
|
||||
f' - TZ={self.timezone}\n'
|
||||
' volumes:\n'
|
||||
f' - {self.config_dir}/radarr-config:/config\n'
|
||||
f' - {self.root_dir}/data:/data\n'
|
||||
f'{self._arr_data_volumes()}'
|
||||
' ports:\n'
|
||||
' - "7878:7878"\n'
|
||||
' restart: unless-stopped\n\n'
|
||||
@@ -122,7 +143,7 @@ class ContainerConfig:
|
||||
f' - TZ={self.timezone}\n'
|
||||
' volumes:\n'
|
||||
f' - {self.config_dir}/bazarr-config:/config\n'
|
||||
f' - {self.root_dir}/data/media:/media\n'
|
||||
f' - {self.media_dir}:/media\n'
|
||||
' ports:\n'
|
||||
' - "6767:6767"\n'
|
||||
' restart: unless-stopped\n\n'
|
||||
@@ -140,7 +161,7 @@ class ContainerConfig:
|
||||
f' - TZ={self.timezone}\n'
|
||||
' volumes:\n'
|
||||
f' - {self.config_dir}/lidarr-config:/config\n'
|
||||
f' - {self.root_dir}/data:/data\n'
|
||||
f'{self._arr_data_volumes()}'
|
||||
' ports:\n'
|
||||
' - "8686:8686"\n'
|
||||
' restart: unless-stopped\n\n'
|
||||
@@ -157,7 +178,7 @@ class ContainerConfig:
|
||||
' - UMASK=002\n'
|
||||
' volumes:\n'
|
||||
f' - {self.config_dir}/mylar-config:/config\n'
|
||||
f' - {self.root_dir}/data:/data\n'
|
||||
f'{self._arr_data_volumes()}'
|
||||
' ports:\n'
|
||||
' - "8090:8090"\n'
|
||||
' restart: unless-stopped\n\n'
|
||||
@@ -173,9 +194,9 @@ class ContainerConfig:
|
||||
f' - TZ={self.timezone}\n'
|
||||
' volumes:\n'
|
||||
f' - {self.config_dir}/audiobookshelf:/config\n'
|
||||
f' - {self.root_dir}/data/media/audiobooks:/audiobooks\n'
|
||||
f' - {self.root_dir}/data/media/podcasts:/podcasts\n'
|
||||
f' - {self.root_dir}/data/media/audiobookshelf-metadata:/metadata\n'
|
||||
f' - {self.media_dir}/audiobooks:/audiobooks\n'
|
||||
f' - {self.media_dir}/podcasts:/podcasts\n'
|
||||
f' - {self.media_dir}/audiobookshelf-metadata:/metadata\n'
|
||||
' ports:\n'
|
||||
' - "13378:80"\n'
|
||||
' restart: unless-stopped\n\n'
|
||||
|
||||
Reference in New Issue
Block a user