fix(deployer): chown 경고 제거 — numeric UID/GID + idempotent 처리

Synology ACL이 username 기반 chown을 거부하고 컨테이너 내부에 bgg8988
사용자가 없어 매 배포마다 WARN 로그가 쏟아지던 문제 해결.

- PUID/PGID 환경변수를 deployer 컨테이너에 전달
- find로 소유자가 다른 항목만 골라 numeric chown (idempotent)
- 실패는 silent — 어차피 파일 기능엔 영향 없음

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-15 20:33:16 +09:00
parent 6f62b34b12
commit 447c6babc3
2 changed files with 26 additions and 24 deletions

View File

@@ -205,6 +205,8 @@ services:
environment: environment:
- TZ=${TZ:-Asia/Seoul} - TZ=${TZ:-Asia/Seoul}
- WEBHOOK_SECRET=${WEBHOOK_SECRET} - WEBHOOK_SECRET=${WEBHOOK_SECRET}
- PUID=${PUID:-1026}
- PGID=${PGID:-100}
volumes: volumes:
- ${REPO_PATH}:/repo:rw - ${REPO_PATH}:/repo:rw
- ${RUNTIME_PATH}:/runtime:rw - ${RUNTIME_PATH}:/runtime:rw

View File

@@ -34,9 +34,9 @@ cd "$SRC"
# 레포에서 운영으로 반영할 항목들만 복사/동기화 # 레포에서 운영으로 반영할 항목들만 복사/동기화
RSYNC_OPTS="-rl --delete --no-owner --no-group --exclude .git --exclude __pycache__ --exclude *.pyc --exclude data/" RSYNC_OPTS="-rl --delete --no-owner --no-group --exclude .git --exclude __pycache__ --exclude *.pyc --exclude data/"
# 파일 권한 설정값 # 파일 권한 설정값 (numeric UID/GID 사용 — 컨테이너에 username 없을 수 있음)
DEPLOY_USER="bgg8988" DEPLOY_UID="${PUID:-1026}"
DEPLOY_GROUP="users" DEPLOY_GID="${PGID:-100}"
DEPLOY_MODE="755" DEPLOY_MODE="755"
for dir in $SERVICES; do for dir in $SERVICES; do
@@ -62,28 +62,28 @@ rsync -rl --no-owner --no-group "$SRC/docker-compose.yml" "$DST/docker-compose.y
fi fi
} }
# 파일 권한 설정 — bgg8988:users 755 # 파일 권한 설정 — numeric UID/GID + idempotent (이미 맞으면 skip) + silent
# 에러는 로그로 남기되 배포는 계속 (Synology ACL 이슈가 있어도 서비스 자체는 동작) # Synology ACL이 chown을 거부할 수 있어도 파일이 이미 올바른 소유자면 문제없음
echo "Setting ownership ${DEPLOY_USER}:${DEPLOY_GROUP} and mode ${DEPLOY_MODE}..." echo "Setting ownership ${DEPLOY_UID}:${DEPLOY_GID} and mode ${DEPLOY_MODE}..."
CHOWN_FAILED=0 chown_if_needed() {
for dir in $SERVICES; do local target="$1"
# 디렉토리 자체 + 내부 항목 모두 재귀 chown (trailing slash 제거) [ -e "$target" ] || return 0
if [ -e "$DST/$dir" ]; then local cur
if ! chown -R "${DEPLOY_USER}:${DEPLOY_GROUP}" "$DST/$dir"; then cur=$(stat -c '%u:%g' "$target" 2>/dev/null || echo "")
echo "WARN: chown failed for $DST/$dir" if [ "$cur" = "${DEPLOY_UID}:${DEPLOY_GID}" ]; then
CHOWN_FAILED=1 return 0
fi fi
chmod -R "$DEPLOY_MODE" "$DST/$dir" || echo "WARN: chmod failed for $DST/$dir" chown "${DEPLOY_UID}:${DEPLOY_GID}" "$target" 2>/dev/null || true
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"
if [ "$CHOWN_FAILED" = "1" ]; then for dir in $SERVICES; do
echo "NOTE: 일부 파일 소유권 설정 실패. NAS에서 직접 'sudo chown -R ${DEPLOY_USER}:${DEPLOY_GROUP} $DST' 실행 권장" [ -e "$DST/$dir" ] || continue
fi # 재귀: 디렉토리/파일 각각 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" echo "SYNC_OK"