LibrePortal/scripts/docker/compose/copy_build_context.sh
librelad 2c907b25c2 refactor(de-sudo): compose/setup/run misc off raw sudo
- copy_build_context: rsync/cp/rm -> runFileOp (writes the deployed tree AS the
  container owner with --no-owner); drop the now-redundant runSystem chown.
- setup_lock: .setup_complete is in the docker-install-owned frontend/data ->
  runFileOp touch/chmod/rm (drop the chown).
- tags_processor_docker_installation 'user:' enable + update_compose_yml
  jail.local -> runFileOp (deployed compose/config under containers).
- crontab_clear: clear the manager's own crontab via runInstallOp.
- reinstall: cp init.sh to /root -> runSystem (genuine root path).
- create_successful_run_file: drop the pointless sudo echo -> runInstallWrite to
  /docker/run.txt.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-24 17:35:09 +01:00

64 lines
2.6 KiB
Bash

#!/bin/bash
# Apps with `build: .` in their docker compose need their Dockerfile +
# source tree to live in the deployed container dir (where compose runs
# from), not just in the install template dir. dockerComposeSetupFile
# only copies the compose itself; this helper covers the rest.
#
# Auto-detect: if a Dockerfile exists in the install dir for the app,
# we copy every file/folder from install→deployed except docker-compose
# variants (already handled) and the .config (per-app config has its
# own copy lifecycle in dockerConfigSetupToContainer).
#
# Idempotent: re-running mirrors the latest install template. Safe to
# call on every install action.
dockerCopyBuildContext()
{
local app_name="$1"
local source_dir="$install_containers_dir$app_name"
local target_dir="$containers_dir$app_name"
if [[ -z "$app_name" ]]; then
isError "dockerCopyBuildContext: app_name is empty."
return 1
fi
if [[ ! -f "$source_dir/Dockerfile" ]]; then
# Nothing to do — app uses a pre-built image.
return 0
fi
if [[ ! -d "$target_dir" ]]; then
isError "dockerCopyBuildContext: target $target_dir doesn't exist."
return 1
fi
isNotice "Copying build context (Dockerfile + source)"
# Use rsync if available so re-installs only diff what changed; fall
# back to cp -R for systems without rsync. Either way we exclude the
# files that have their own copy lifecycle.
# --no-owner --no-group: don't carry the install template's ownership (the
# repo clone is owned by the human user, uid ~1000) onto the deployed
# container dir — the chown below sets the correct owner. Without this the
# rsync re-stamps the WebUI tree as uid 1000 every install.
if command -v rsync >/dev/null 2>&1; then
runFileOp rsync -a --no-owner --no-group \
--exclude="docker-compose.yml" \
--exclude="docker-compose.${app_name}.yml" \
--exclude="${app_name}.config" \
--exclude="${app_name}.tools.json" \
--exclude="${app_name}.svg" \
--exclude="data" \
"$source_dir/" "$target_dir/"
else
# Best-effort fallback. Copies everything then nukes the
# excluded items in the target.
runFileOp cp -R "$source_dir/." "$target_dir/"
runFileOp rm -f "$target_dir/${app_name}.config" "$target_dir/${app_name}.tools.json"
fi
# runFileOp above wrote the tree AS the container owner (rootless: the docker
# install user; rooted: the manager) with --no-owner so the repo-clone uid
# isn't carried — no root, no chown needed.
isSuccessful "Build context copied for $app_name."
}