From 988297e8de20f93bacedaf3c3cee50842c8e3912 Mon Sep 17 00:00:00 2001 From: librelad Date: Fri, 28 Aug 2026 08:21:11 +0100 Subject: [PATCH] compose: fall back to docker-compose.yml when the app's config is out of scope MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dockerComposeUp and dockerComposeDown derive compose_file from $compose_setup, which setupBasicScanVariables reads from CFG__COMPOSE_FILE — a variable that is only set once the app's config has been sourced, and is not always. A restore wipes and re-creates the app folder around those calls. setupBasicScanVariables already handles that, falling back to the standard file. Neither compose function did: with compose_setup empty, neither branch ran, compose_file stayed UNSET, and the guard [ ! -f "$(appDir "$app")/$compose_file" ] then tested the app DIRECTORY, which is never a regular file. So the app was reported as having no compose file and quietly not started. Found restoring an app on a clean install: the restore ran to completion and reported success, having neither stopped nor started the app — ---- 3. Shutting down container(s) for restoration ! Notice Unable to find the compose file to docker compose down this application. ---- 10. Starting up the linkding docker service(s) ! Notice Unable to find the compose file to docker compose up this application. — while docker-compose.yml sat in the app directory the whole time. Verified: with CFG_LINKDING_COMPOSE_FILE unset, dockerComposeUp now starts the app. scripts/dev/lp-compose-file-test covers the empty case, the normal one, and a genuinely missing file so the guard still fires when it should. Co-Authored-By: Claude Opus 5 --- scripts/dev/lp-compose-file-test | 63 ++++++++++++++++++++++++++ scripts/docker/app/compose/down_app.sh | 8 ++++ scripts/docker/app/compose/up_app.sh | 8 ++++ 3 files changed, 79 insertions(+) create mode 100755 scripts/dev/lp-compose-file-test diff --git a/scripts/dev/lp-compose-file-test b/scripts/dev/lp-compose-file-test new file mode 100755 index 0000000..82e5d1a --- /dev/null +++ b/scripts/dev/lp-compose-file-test @@ -0,0 +1,63 @@ +#!/bin/bash +# Does compose still find its file when CFG__COMPOSE_FILE is out of scope? +# +# scripts/dev/lp-compose-file-test +# +# dockerComposeUp/Down derive compose_file from $compose_setup, which +# setupBasicScanVariables reads from CFG__COMPOSE_FILE. That variable is +# only set once the app's config has been sourced, and it is not always — a +# restore wipes and re-creates the app folder around those calls. +# +# setupBasicScanVariables already falls back to the standard file for that case. +# The two compose functions did not: with compose_setup empty, neither branch +# ran, compose_file stayed UNSET, and the guard +# +# [ ! -f "$(appDir "$app")/$compose_file" ] +# +# then tested the app DIRECTORY, which is never a regular file. So the app was +# reported as having no compose file and quietly not started — visible only as +# "Unable to find the compose file", with the restore itself reporting success. + +REPO="$(cd "$(dirname "$0")/../.." && pwd)" +BASE="$(mktemp -d "${TMPDIR:-/tmp}/lp-compose-test-XXXXXX")" +trap 'rm -rf "$BASE"' EXIT + +fail=0 +chk(){ if [[ "$2" == "$3" ]]; then echo " ok $1"; else echo " FAIL $1: got '$2' want '$3'"; fail=1; fi; } + +mkdir -p "$BASE/myapp" +: > "$BASE/myapp/docker-compose.yml" + +run() { # run -> prints what the guard decided + local setup="$1" + bash -c ' + OS_TYPE=Ubuntu + appDir(){ printf "%s/%s" "'"$BASE"'" "$1"; } + setupBasicScanVariables(){ :; } + isHeader(){ :; }; isError(){ :; }; isSuccessful(){ :; }; checkSuccess(){ :; } + isNotice(){ echo "NOTICE: $*"; } + # Everything past the guard is docker; stop there. + dockerCommandRunInstallUser(){ echo "REACHED_DOCKER"; } + runFileOp(){ echo "REACHED_DOCKER"; } + compose_setup="'"$setup"'" + source "'"$REPO"'/scripts/docker/app/compose/down_app.sh" + dockerComposeDown myapp 2>/dev/null + ' 2>/dev/null +} + +echo "--- compose_setup=default (the normal path) ---" +out=$(run default) +chk "does not report a missing file" "$(grep -c 'Unable to find' <<< "$out")" "0" + +echo "--- compose_setup empty (config not sourced — the restore case) ---" +out=$(run "") +chk "does not report a missing file" "$(grep -c 'Unable to find' <<< "$out")" "0" + +echo "--- and it genuinely reports a file that is absent ---" +rm -f "$BASE/myapp/docker-compose.yml" +out=$(run "") +chk "reports the missing file" "$(grep -c 'Unable to find' <<< "$out")" "1" + +echo "" +if (( fail )); then echo "FAILED"; exit 1; fi +echo "All compose-file checks passed." diff --git a/scripts/docker/app/compose/down_app.sh b/scripts/docker/app/compose/down_app.sh index 09047df..481e605 100755 --- a/scripts/docker/app/compose/down_app.sh +++ b/scripts/docker/app/compose/down_app.sh @@ -24,6 +24,14 @@ dockerComposeDown() elif [[ $compose_setup == "app" ]]; then local setup_compose="-f docker-compose.yml -f docker-compose.$app_name.yml" local compose_file="docker-compose.$app_name.yml" + else + # setupBasicScanVariables falls back to the standard file when + # CFG__COMPOSE_FILE is not in scope; without the same fallback here + # compose_file stays UNSET, and the existence check below then tests the + # app DIRECTORY — which is never a regular file. The app is reported as + # having no compose file and is quietly not brought down. + local setup_compose="-f docker-compose.yml" + local compose_file="docker-compose.yml" fi if [[ $custom_compose != "" ]]; then local setup_compose="-f docker-compose.yml -f $custom_compose" diff --git a/scripts/docker/app/compose/up_app.sh b/scripts/docker/app/compose/up_app.sh index 21fd5a3..f9046f3 100755 --- a/scripts/docker/app/compose/up_app.sh +++ b/scripts/docker/app/compose/up_app.sh @@ -50,6 +50,14 @@ dockerComposeUp() elif [[ $compose_setup == "app" ]]; then local setup_compose="-f docker-compose.yml -f docker-compose.$app_name.yml" local compose_file="docker-compose.$app_name.yml" + else + # setupBasicScanVariables falls back to the standard file when + # CFG__COMPOSE_FILE is not in scope; without the same fallback here + # compose_file stays UNSET, and the existence check below then tests the + # app DIRECTORY — which is never a regular file. The app is reported as + # having no compose file and is quietly not started. + local setup_compose="-f docker-compose.yml" + local compose_file="docker-compose.yml" fi if [[ $custom_compose != "" ]]; then local setup_compose="-f docker-compose.yml -f $custom_compose"