configFileSetupData runs as the manager (libreportal user) during install,
but writes into /libreportal-containers/<app>/, which is owned by the
container user (dockerinstall) under the three-root layout. The six bare
`sed -i` calls in this function were missing the `runFileOp` wrapper that
every other in-tree sed-on-app-files call already uses (e.g. setup_dns.sh's
WG_DEFAULT_DNS edits), so on first run `sed -i` failed to create its temp
file in the live dir:
sed: couldn't open temporary file /libreportal-containers/linkding/sedaCaUNU: Permission denied
✗ Error Updated DOMAINSUBNAMEHERE with: bookmark.
! Notice Non-interactive mode: aborting on error.
…which aborted the install at step 3 of every per-app config setup.
Replace `result=$(sed -i ...)` with `result=$(runFileOp sed -i ...)` so each
substitution runs as the owner of the target file (via the bin-install
helper). All six call sites use the same pattern — done as a single
`replace_all` over the unique prefix.
Tags fixed: DOMAINSUBNAMEHERE, APPADDRESSHERE, DOMAINSUBNAME_DATA,
TIMEZONE_DATA, EMAILHERE, HOSTIPHERE.
Verified live on a fresh install: `libreportal app install linkding` now
completes cleanly through all 10 install steps and lands the container.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
Application backups were driven by one crontab entry per app, each offset by
id * CFG_BACKUP_CRONTAB_APP_INTERVAL minutes. That minute offset is written
straight into cron's 0-59 minute field, so past ~20 apps it overflowed into
an invalid entry that silently never fired, and the fixed spacing could not
serialize backups that ran longer than the gap.
Replace it with a single daily entry (`libreportal backup scheduled`) that
enqueues a backup task per enabled app. The existing systemd task processor
drains them serially — no minute overflow, real serialization, and backups
are now visible/cancellable in the Tasks UI. Per-app enable is read from
CFG_<APP>_BACKUP at schedule time instead of being mirrored into crontab.
Removes the stagger machinery (timing/setup/check/remove scripts), the
now-unused cron_jobs table + insert, and the CFG_BACKUP_CRONTAB_APP_INTERVAL
config knob and its WebUI field.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
Propagate the ✓ Success / ✗ Error / ! Notice / ❯ Question glyphs (from markers.sh) through the rest of the pipeline: swap the inlined helpers in init.sh and generate_arrays.sh, and replace raw echo -e "${RED}ERROR:${NC}" calls with the isX helpers in config_check_missing.sh, check_success.sh, initilize_files.sh, and reset_git.sh.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
Replaces the slow, interactive per-variable scan with a deterministic
reconcile: each live config is rebuilt from its (freshly-cloned) template —
keeping the user's existing values, adding new template keys
(CFG_REQUIREMENT_CONFIGS_AUTO_UPDATE), and dropping keys the template no
longer defines (new CFG_REQUIREMENT_CONFIGS_AUTO_DELETE, default true).
Structure/order/comments follow the template; non-interactive; atomic with a
.bak; refuses to act on a missing/empty template so a broken clone can't wipe
a config. Applies to both general and per-app configs.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
A free, open, self-hosted app platform (GNU AGPLv3): one-click app deploys,
Traefik reverse proxy with automatic SSL, rootless Docker support, gluetun
VPN routing, and a web dashboard to manage it all.
Free & open forever to self-host; optional paid hosted services fund it.
See PROMISE.md.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>