From 447c6babc3d83960753eb8765d9e7709c6be508a Mon Sep 17 00:00:00 2001 From: gahusb Date: Wed, 15 Apr 2026 20:33:16 +0900 Subject: [PATCH] =?UTF-8?q?fix(deployer):=20chown=20=EA=B2=BD=EA=B3=A0=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0=20=E2=80=94=20numeric=20UID/GID=20+=20idempo?= =?UTF-8?q?tent=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Synology ACL이 username 기반 chown을 거부하고 컨테이너 내부에 bgg8988 사용자가 없어 매 배포마다 WARN 로그가 쏟아지던 문제 해결. - PUID/PGID 환경변수를 deployer 컨테이너에 전달 - find로 소유자가 다른 항목만 골라 numeric chown (idempotent) - 실패는 silent — 어차피 파일 기능엔 영향 없음 Co-Authored-By: Claude Opus 4.6 --- docker-compose.yml | 2 ++ scripts/deploy-nas.sh | 48 +++++++++++++++++++++---------------------- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index debb3d2..29ace82 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -205,6 +205,8 @@ services: environment: - TZ=${TZ:-Asia/Seoul} - WEBHOOK_SECRET=${WEBHOOK_SECRET} + - PUID=${PUID:-1026} + - PGID=${PGID:-100} volumes: - ${REPO_PATH}:/repo:rw - ${RUNTIME_PATH}:/runtime:rw diff --git a/scripts/deploy-nas.sh b/scripts/deploy-nas.sh index d3a3048..a4308b0 100644 --- a/scripts/deploy-nas.sh +++ b/scripts/deploy-nas.sh @@ -34,9 +34,9 @@ cd "$SRC" # 레포에서 운영으로 반영할 항목들만 복사/동기화 RSYNC_OPTS="-rl --delete --no-owner --no-group --exclude .git --exclude __pycache__ --exclude *.pyc --exclude data/" -# 파일 권한 설정값 -DEPLOY_USER="bgg8988" -DEPLOY_GROUP="users" +# 파일 권한 설정값 (numeric UID/GID 사용 — 컨테이너에 username 없을 수 있음) +DEPLOY_UID="${PUID:-1026}" +DEPLOY_GID="${PGID:-100}" DEPLOY_MODE="755" for dir in $SERVICES; do @@ -62,28 +62,28 @@ rsync -rl --no-owner --no-group "$SRC/docker-compose.yml" "$DST/docker-compose.y fi } -# 파일 권한 설정 — bgg8988:users 755 -# 에러는 로그로 남기되 배포는 계속 (Synology ACL 이슈가 있어도 서비스 자체는 동작) -echo "Setting ownership ${DEPLOY_USER}:${DEPLOY_GROUP} and mode ${DEPLOY_MODE}..." -CHOWN_FAILED=0 -for dir in $SERVICES; do - # 디렉토리 자체 + 내부 항목 모두 재귀 chown (trailing slash 제거) - if [ -e "$DST/$dir" ]; then - if ! chown -R "${DEPLOY_USER}:${DEPLOY_GROUP}" "$DST/$dir"; then - echo "WARN: chown failed for $DST/$dir" - CHOWN_FAILED=1 - fi - chmod -R "$DEPLOY_MODE" "$DST/$dir" || echo "WARN: chmod failed for $DST/$dir" +# 파일 권한 설정 — numeric UID/GID + idempotent (이미 맞으면 skip) + silent +# Synology ACL이 chown을 거부할 수 있어도 파일이 이미 올바른 소유자면 문제없음 +echo "Setting ownership ${DEPLOY_UID}:${DEPLOY_GID} and mode ${DEPLOY_MODE}..." +chown_if_needed() { + local target="$1" + [ -e "$target" ] || return 0 + local cur + cur=$(stat -c '%u:%g' "$target" 2>/dev/null || echo "") + if [ "$cur" = "${DEPLOY_UID}:${DEPLOY_GID}" ]; then + return 0 fi -done -if ! chown "${DEPLOY_USER}:${DEPLOY_GROUP}" "$DST/docker-compose.yml"; then - echo "WARN: chown failed for $DST/docker-compose.yml" - CHOWN_FAILED=1 -fi -chmod "$DEPLOY_MODE" "$DST/docker-compose.yml" || echo "WARN: chmod failed for docker-compose.yml" + chown "${DEPLOY_UID}:${DEPLOY_GID}" "$target" 2>/dev/null || true +} -if [ "$CHOWN_FAILED" = "1" ]; then - echo "NOTE: 일부 파일 소유권 설정 실패. NAS에서 직접 'sudo chown -R ${DEPLOY_USER}:${DEPLOY_GROUP} $DST' 실행 권장" -fi +for dir in $SERVICES; do + [ -e "$DST/$dir" ] || continue + # 재귀: 디렉토리/파일 각각 idempotent chown (find로 mismatch만 시도) + find "$DST/$dir" \( ! -uid "$DEPLOY_UID" -o ! -gid "$DEPLOY_GID" \) \ + -exec chown "${DEPLOY_UID}:${DEPLOY_GID}" {} + 2>/dev/null || true + chmod -R "$DEPLOY_MODE" "$DST/$dir" 2>/dev/null || true +done +chown_if_needed "$DST/docker-compose.yml" +chmod "$DEPLOY_MODE" "$DST/docker-compose.yml" 2>/dev/null || true echo "SYNC_OK"