Skip to content

feat: Make core.wwwdir and core.pluginsdir user-configurable to support split storage setups #419

@antonkarliner

Description

@antonkarliner

Is your feature request related to a problem? Please describe.

When core.datadir is set to an absolute path pointing to external/network storage (e.g. a NAS share or a Home Assistant network mount), TeddyCloud becomes unable to serve the web GUI. This is because internal.wwwdirfull is always resolved as {datadirfull}/www, but in containerised deployments the www assets are baked into the container image at a fixed internal path — they are never on the external storage volume.

The split-storage use case is legitimate and common: keep large content/library files on slow external storage, while server binaries and web assets stay on fast internal storage. Currently this configuration is impossible to achieve cleanly because there is no way to point wwwdirfull at the container-internal www path independently of core.datadir.

To reproduce:

Set core.datadir to an absolute path that differs from the container-internal data directory, e.g.:

core.datadir=/mnt/nas/teddycloud
core.contentdir=/mnt/nas/teddycloud/content/default
core.librarydir=/mnt/nas/teddycloud/library

TeddyCloud will fail sanity checks or serve 404s for all web UI requests, because it looks for www assets at /mnt/nas/teddycloud/www instead of the container-internal /teddycloud/data/www.

Error in logs:

ERROR|server.c:0758:sanityCheckDir()| Config item 'internal.wwwdirfull' is set to '/mnt/nas/teddycloud/www' which was not found

Or if the directory is manually created (empty), the server starts but all web requests return 404.

Describe the solution you'd like

Promote core.wwwdir (and core.pluginsdir) from OPTION_INTERNAL_STRING to OPTION_STRING in src/settings.c, making them user-configurable via config.ini just like core.contentdir, core.librarydir, core.firmwaredir, and core.cachedir already are.

Current code (src/settings.c):

OPTION_INTERNAL_STRING("core.wwwdir", &settings->core.wwwdir, "www", "WWW dir", LEVEL_NONE)
OPTION_INTERNAL_STRING("core.pluginsdir", &settings->core.pluginsdir, "plugins", "plugins dir", LEVEL_NONE)

Proposed change:

OPTION_STRING("core.wwwdir", &settings->core.wwwdir, "www", "WWW dir", "Directory for web UI assets (relative to datadir, or absolute)", LEVEL_EXPERT)
OPTION_STRING("core.pluginsdir", &settings->core.pluginsdir, "plugins", "Plugins dir", "Directory for web plugins (relative to wwwdir, or absolute)", LEVEL_EXPERT)

This is consistent with how all other data directories are already handled, and the default value "www" preserves full backwards compatibility.

Describe alternatives you've considered

  1. Setting core.datadir to / — works as a security boundary but breaks other internal path derivations and is a security concern.
  2. Symlinking — not possible in containerised environments like Home Assistant OS where the container filesystem is inaccessible from the host.
  3. Manually copying www assets to external storage — works as a workaround (extract from the release zip), but the www files then go stale on every TeddyCloud update and must be manually re-synced. Not viable long-term.
  4. Setting core.datadir to a path that covers both locations — impossible when www lives inside the container and content lives on external storage, as no single path can be an ancestor of both.

Additional context

This affects the Home Assistant addon (mrueg/addon-teddycloud) when used with network storage, but the root cause is in the core teddycloud settings system.

The addon mounts config at /addon_configs/.../teddycloud/ (fast internal HA Green SSD) but users may want content/library on a network share at /share/teddycloud/teddycloud/. With the current design, pointing core.datadir at the share breaks www; leaving it at data means the path security check in handler_cloud.c (osStrncmp(tonieInfo->contentPath, client_ctx->settings->internal.datadirfull, dataPathLen)) blocks serving any content from the share.

Technical details:

  • Version: tc_v0.6.7 (5b59a82-dirty)
  • Home Assistant OS 17.1 (aarch64 / green)
  • HA Add-on version: 0.5.4
  • Home Assistant Core: 2026.2.2

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions