From 0dfb5b45d2e45deec98e46771c51e5fd473e9bf0 Mon Sep 17 00:00:00 2001 From: Hannes Ahlin Date: Sat, 22 Aug 2026 15:30:25 +0200 Subject: [PATCH] Fix docker build context permanently via .dockerignore + tar verify --- integrate/dockerignore.snippet | 14 ++++ scripts/fix-docker-build-context.sh | 28 ++++++++ scripts/integrate-into-nodered.sh | 99 +++++++++++++++++++++++------ 3 files changed, 123 insertions(+), 18 deletions(-) create mode 100644 integrate/dockerignore.snippet create mode 100644 scripts/fix-docker-build-context.sh diff --git a/integrate/dockerignore.snippet b/integrate/dockerignore.snippet new file mode 100644 index 0000000..a299c58 --- /dev/null +++ b/integrate/dockerignore.snippet @@ -0,0 +1,14 @@ +# Hanteras av nextcloud-collabora-nodered (integrate) — exkludera från build context +# Dessa filer behövs inte i imagen och kan ha restriktiva rättigheter lokalt. + +# Lokal odds-scraper-binär (ej runtime — npm-paketet i imagen byggs från package.json) +nodes/odds-scraper/odds-scraper + +# Övrigt skräp / stora filer i projektroten +.git +.vscode +**/*.deb +winboat* + +# Node-moduler på host (installeras i Dockerfile) +**/node_modules diff --git a/scripts/fix-docker-build-context.sh b/scripts/fix-docker-build-context.sh new file mode 100644 index 0000000..0833d3f --- /dev/null +++ b/scripts/fix-docker-build-context.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# Engångsfix på servern om docker build context failar +set -euo pipefail +NODERED_DIR="${1:-/home/ncadmin/nextcloud-node-red}" +USER="${2:-ncadmin}" +DI="${NODERED_DIR}/.dockerignore" + +echo "[fix] ${NODERED_DIR}" + +chown -R "${USER}:${USER}" "${NODERED_DIR}" +find "${NODERED_DIR}/nodes" -type d -exec chmod u+rwx,go+rx {} + 2>/dev/null || true +find "${NODERED_DIR}/nodes" -type f -exec chmod u+rw,go+r {} + 2>/dev/null || true + +if ! grep -q "nextcloud-collabora-nodered" "${DI}" 2>/dev/null; then + cat >> "${DI}" <<'EOF' + +# nextcloud-collabora-nodered +nodes/odds-scraper/odds-scraper +.git +.vscode +**/*.deb +winboat* +**/node_modules +EOF +fi + +tar -cf /dev/null --exclude-from="${DI}" -C "${NODERED_DIR}" . \ + && echo "[fix] Build context OK — kör ./install.sh" diff --git a/scripts/integrate-into-nodered.sh b/scripts/integrate-into-nodered.sh index 27e39e7..2d3bb9c 100644 --- a/scripts/integrate-into-nodered.sh +++ b/scripts/integrate-into-nodered.sh @@ -36,26 +36,93 @@ runtime_user() { fi } -# Docker build context måste kunna läsa nodes/ (inkl. odds-scraper — rör inte innehållet) +# Docker build context — .dockerignore + rättigheter (undviker permission denied) +DOCKERIGNORE_MARKER="nextcloud-collabora-nodered" + +patch_dockerignore() { + local di="${NODERED_DIR}/.dockerignore" + local snippet="${PKG_SRC}/integrate/dockerignore.snippet" + + if [ ! -f "${di}" ]; then + log "Skapar .dockerignore" + touch "${di}" + fi + + if ! grep -q "${DOCKERIGNORE_MARKER}" "${di}" 2>/dev/null; then + log "Patchar .dockerignore (exkluderar oläsbara lokala artefakter)" + { + echo "" + echo "# ${DOCKERIGNORE_MARKER}" + if [ -f "${snippet}" ]; then + cat "${snippet}" + else + echo "nodes/odds-scraper/odds-scraper" + echo ".git" + echo ".vscode" + echo "**/*.deb" + echo "winboat*" + echo "**/node_modules" + fi + } >> "${di}" + fi + + # Dynamiskt: alla filer under nodes/ som inte ens root kan läsa → ignorera + local unreadable + while IFS= read -r relpath; do + [ -n "${relpath}" ] || continue + if ! grep -qxF "${relpath}" "${di}" 2>/dev/null; then + log " + .dockerignore: ${relpath} (oläsbar)" + echo "${relpath}" >> "${di}" + fi + done < <(run_as_root find "${NODERED_DIR}/nodes" -type f ! -readable -printf '%P\n' 2>/dev/null || true) +} + fix_nodered_build_permissions() { local user group user="$(runtime_user)" group="$(id -gn "${user}" 2>/dev/null || echo "${user}")" + if [ ! -d "${NODERED_DIR}/nodes" ]; then return 0 fi - if run_as_root test -r "${NODERED_DIR}/nodes/odds-scraper" 2>/dev/null; then - : # root kan läsa - else - warn "nodes/odds-scraper oläsbar — fixar läsrättigheter för build (innehåll orört)" - fi - log "Säkerställer läsbar Docker build context under ${NODERED_DIR}/nodes" - run_as_root find "${NODERED_DIR}/nodes" -type d -exec chmod a+rx {} + 2>/dev/null || true - run_as_root find "${NODERED_DIR}/nodes" -type f -exec chmod a+r {} + 2>/dev/null || true - # Alternativt: ge ncadmin ägarskap om katalogen ägs av root - if [ "$(stat -c '%U' "${NODERED_DIR}" 2>/dev/null)" = "root" ]; then - run_as_root chown -R "${user}:${group}" "${NODERED_DIR}" + + log "Fixar ägande och läsrättigheter för ${NODERED_DIR} (innehåll orört)" + run_as_root chown -R "${user}:${group}" "${NODERED_DIR}" + run_as_root find "${NODERED_DIR}/nodes" -type d -exec chmod u+rwx,go+rx {} + 2>/dev/null || true + run_as_root find "${NODERED_DIR}/nodes" -type f -exec chmod u+rw,go+r {} + 2>/dev/null || true + + # Binärer som ska vara körbara + run_as_root find "${NODERED_DIR}/nodes" -type f \( -name "*.sh" -o -name "odds-scraper" \) -exec chmod u+rx,go+rx {} + 2>/dev/null || true +} + +# Simulera Docker build context — måste lyckas innan build +verify_build_context() { + local di="${NODERED_DIR}/.dockerignore" + local errfile + errfile="$(mktemp)" + + log "Verifierar Docker build context..." + patch_dockerignore + + if ! run_as_root tar -cf /dev/null \ + --exclude-from="${di}" \ + -C "${NODERED_DIR}" . 2>"${errfile}"; then + warn "Build context-fel:" + sed 's/^/[integrate] /' "${errfile}" >&2 || true + # Sista utväg: tvinga bort kända problemfil + if [ -f "${NODERED_DIR}/nodes/odds-scraper/odds-scraper" ]; then + echo "nodes/odds-scraper/odds-scraper" >> "${di}" + log "Tvingade nodes/odds-scraper/odds-scraper in i .dockerignore" + fi + if ! run_as_root tar -cf /dev/null \ + --exclude-from="${di}" \ + -C "${NODERED_DIR}" . 2>"${errfile}"; then + rm -f "${errfile}" + die "Build context oläsbar efter .dockerignore — se ${di}" + fi fi + rm -f "${errfile}" + log "Build context OK" } compose_cmd() { @@ -66,16 +133,12 @@ compose_cmd() { fi } -# sudo docker compose: root läser hela build context (fixar permission denied på odds-scraper) +# Alltid root för compose build — samma användare som kan läsa hela trädet + .dockerignore compose_run() { local compose compose="$(compose_cmd)" cd "${NODERED_DIR}" - if [ "$(id -u)" -eq 0 ]; then - ${compose} "$@" - else - run_as_root ${compose} "$@" - fi + run_as_root env DOCKER_BUILDKIT=1 ${compose} "$@" } resolve_paths() {