The shell fallback was assigned locally but never exported, so
sync_watcher.py and the Python config layer never saw the resolved
value. They happened to land on the same /var/lib/romm/sync default by
coincidence; export it so the shell and Python defaults stay linked
through a single source of truth.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The prod Dockerfile creates /var/lib/romm/sync at build time, but if a
user overrides SYNC_BASE_PATH to a path that doesn't exist (or runs the
dev entrypoint, which never created the default), watchfiles fails to
start because its target directory is missing. Have both entrypoints
mkdir -p the resolved path before handing it to watchfiles.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Move the sync staging folder out of ROMM_BASE_PATH so it lives on a
dedicated writable mount. This lets the container run with a read-only
root filesystem without losing in-flight save uploads, and keeps
app-owned state separate from the user-curated library volume.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The init script ran `sed -i` against /etc/gunicorn/logging.conf, which
fails both on read-only root filesystems and when the container runs
as a non-root UID (since /etc/gunicorn is not chmod'd writable). Copy
the config to /tmp/gunicorn/logging.conf at startup and edit/use that
copy instead, leaving the image file untouched.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The gunicorn logging config hard-coded level=INFO, ignoring LOGLEVEL.
Patch it at startup via sed. Also pass --logging_level to rq worker
and rqscheduler so their framework logging respects LOGLEVEL.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When OTEL_SDK_DISABLED=true (set automatically when no OTEL_ env vars
are present), the opentelemetry-instrument wrapper does not properly
pass through the WATCHFILES_CHANGES environment variable to watcher.py.
This causes the filesystem watcher to silently fail - watchfiles detects
changes but watcher.py receives an empty WATCHFILES_CHANGES and exits
immediately without scheduling any rescans.
The fix skips the opentelemetry-instrument wrapper when OTEL is disabled,
allowing watchfiles to pass WATCHFILES_CHANGES directly to watcher.py.
Fixes automatic rescan on filesystem change for users who don't configure
OpenTelemetry (the majority of self-hosted deployments).