From 5a1acb6f85102bf309502cba041f261e276f51d8 Mon Sep 17 00:00:00 2001 From: Lucian Behind The Scenes Date: Wed, 25 Feb 2026 16:03:12 +0200 Subject: [PATCH] fix: set group-writable permissions on shared storage during deploy Add set_group_writable_tree helper to keep shared storage paths writable for both the deploy user and PHP-FPM (www-data). Applies SGID + 2775 on directories and 664 on files so new entries inherit the group. Also cleans up YAML sequence formatting in inventory.yml. --- .deployer/inventory.yml | 6 +++-- .deployer/scripts/deploy.sh | 44 ++++++++++++++++++++++++++++++++++--- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/.deployer/inventory.yml b/.deployer/inventory.yml index d7510f6..d0cf9dc 100644 --- a/.deployer/inventory.yml +++ b/.deployer/inventory.yml @@ -1,5 +1,6 @@ servers: - - name: deployerphp + - + name: deployerphp host: 165.245.136.228 port: 22 username: root @@ -8,7 +9,8 @@ servers: dropletId: 547535778 instanceId: null sites: - - domain: deployerphp.com + - + domain: deployerphp.com server: deployerphp repo: 'git@github.com:loadinglucian/deployerphp.com.git' branch: main diff --git a/.deployer/scripts/deploy.sh b/.deployer/scripts/deploy.sh index 6aba0d5..7b9a32c 100644 --- a/.deployer/scripts/deploy.sh +++ b/.deployer/scripts/deploy.sh @@ -18,6 +18,34 @@ set -euo pipefail # # You're automatically in the DEPLOYER_RELEASE_PATH directory at this point: +# +# Permissions helper +# ---- +# +# Code runs with PHP-FPM as `www-data` while deploy commands run as +# `deployer`. In DeployerPHP setups, `www-data` is added to the +# `deployer` group so both can write to shared runtime paths. +# +# This helper keeps shared writable trees consistent: +# - Directories: `2775` (`rwxrwxr-x` + SGID bit) +# - Files: `664` (`rw-rw-r--`) +# +# The leading `2` in `2775` enables SGID on directories, so newly created +# files/directories inherit the parent directory group instead of the creator's +# primary group. + +set_group_writable_tree() { + local path="$1" + + 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 {} + +} + # ---- # Framework Detection # ---- @@ -41,7 +69,10 @@ 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" + 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" echo "→ Linking shared storage..." rm -rf "${DEPLOYER_RELEASE_PATH}/storage" @@ -51,6 +82,10 @@ if [[ $framework == "laravel" ]]; then mkdir -p "${DEPLOYER_SHARED_PATH}/database" touch "${DEPLOYER_SHARED_PATH}/database/database.sqlite" + # Keep sqlite path writable for both deploy user and PHP-FPM group member: + chmod 2775 "${DEPLOYER_SHARED_PATH}/database" + chmod 664 "${DEPLOYER_SHARED_PATH}/database/database.sqlite" + echo "→ Linking shared database.sqlite..." ln -sf "${DEPLOYER_SHARED_PATH}/database/database.sqlite" "${DEPLOYER_RELEASE_PATH}/database/database.sqlite" fi @@ -129,9 +164,12 @@ 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: + set_group_writable_tree "${DEPLOYER_SHARED_PATH}/storage" - echo "→ Clearing docs output cache..." - "${DEPLOYER_PHP}" artisan docs:clear fi # Symfony (uncomment as needed)