From 4b7108a195f1b268e82de27a163bba7b876afeee Mon Sep 17 00:00:00 2001 From: Lucian Behind The Scenes Date: Wed, 25 Feb 2026 18:29:16 +0200 Subject: [PATCH] fix: only chmod files owned by deploy user in shared storage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When artisan optimize runs view:cache, it skips views already compiled by PHP-FPM (www-data) and left in shared storage. The subsequent set_group_writable_tree call then fails with "Operation not permitted" because chmod cannot be run on files owned by another user. Filter both find commands with -user to target only deployer-owned entries and suppress errors with 2>/dev/null so mixed-ownership storage directories don't abort the deployment. Also removes the docs:clear artisan call and docs-output/.locks mkdir from the deploy script — the optimize:clear step already handles cache clearing and the locks directory is created on demand. --- .deployer/scripts/deploy.sh | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/.deployer/scripts/deploy.sh b/.deployer/scripts/deploy.sh index 7b9a32c..73aa818 100644 --- a/.deployer/scripts/deploy.sh +++ b/.deployer/scripts/deploy.sh @@ -36,14 +36,19 @@ set -euo pipefail set_group_writable_tree() { local path="$1" + local current_user if [[ ! -d "${path}" ]]; then return fi - # Keep shared writable trees group-writable and SGID so new entries inherit group. - find "${path}" -type d -exec chmod 2775 {} + - find "${path}" -type f -exec chmod 664 {} + + current_user="$(id -un)" + + # chmod can only be performed by file owner (or root). During runtime some + # cache files may be owned by www-data, so normalize only deployer-owned + # entries and do not fail deployment if skipped files exist. + find "${path}" -type d -user "${current_user}" -exec chmod 2775 {} + 2> /dev/null || true + find "${path}" -type f -user "${current_user}" -exec chmod 664 {} + 2> /dev/null || true } # ---- @@ -69,7 +74,6 @@ if [[ $framework == "laravel" ]]; then echo "→ Ensuring shared storage directories..." mkdir -p "${DEPLOYER_SHARED_PATH}/storage/"{app,framework,logs} mkdir -p "${DEPLOYER_SHARED_PATH}/storage/framework/"{cache,sessions,views} - mkdir -p "${DEPLOYER_SHARED_PATH}/storage/framework/cache/docs-output/.locks" # Make shared storage writable for both deploy user and PHP-FPM group member: set_group_writable_tree "${DEPLOYER_SHARED_PATH}/storage" @@ -164,7 +168,6 @@ if [[ $framework == "laravel" ]]; then echo "→ Optimizing..." "${DEPLOYER_PHP}" artisan optimize:clear "${DEPLOYER_PHP}" artisan optimize - "${DEPLOYER_PHP}" artisan docs:clear # Artisan commands can create new cache/session/log paths. Re-apply permissions # to keep shared storage writable for both deploy user and PHP-FPM group member: