Capifony has a cookbook entry explaining how to automatically set proper permissions. Basically what you need is this:
set :writable_dirs, ["app/cache", "app/logs"]
set :webserver_user, "www-data"
set :permission_method, :acl
set :use_set_permissions, true
:use_sudo
doesn't need to be true
as long as the :writable_dirs
are owned by :user
.
The problem
setfacl: /var/www/releases/20140310012814/app/cache/prod/classes.php: Operation not permitted
This message indicates that the cache directory isn't empty when the task is run (setfacl
operates on prod/classes.php
in that directory), which is not owned by :user
(setfacl
is not permitted).
The fact that the file is not owned by :user
is quite normal because the webserver will create a lot of cache files, which make them owned by :webserver_user
.
The strange thing here is that the cache directory isn't empty. Normally a new release should have an empty cache directory. A common cause for this is that the cache directory is shared, meaning you've added it to :shared_children
. If so, please remove it. The cache directory shouldn't be shared.
If this is not the case, then try to find out why the cache directory isn't empty when the setfacl
task is run. Maybe other tasks are running to soon.
Writable shared children
What if you actually want a shared directory to be writable for the webserver? This is actually very common, think of a media
or uploads
directory that should be shared.
The permissions should be set on the actual shared directory, not the symlink in the release directory. Capifony takes care of this for you, as long as the exact same phrase in :writable_dirs
is also in :shared_children
.
# this will work:
set :shared_children, ["web/uploads"]
set :writable_dirs, ["web/uploads"]
# this will also work:
set :web_path, "web" # is default
set :shared_children, [web_path + "/uploads"]
set :writable_dirs, ["web/uploads"]
# this will not:
set :web_path, "web" # is default
set :shared_children, [web_path + "/uploads"]
set :writable_dirs, ["web/uploads/"] # trailing /
Please check if the directory mentioned in the error is the actual shared directory (not the symlink).
The owner of the shared directory must be the user that will run the setfacl
command. In other words, it must be :user
. When you've changed the value of :user
, or have had :use_sudo
enabled in the past, this could cause issues. Please check if the directories (as set in :writable_dirs
) are indeed owned by :user
.
Capifony will perform a check if the permissions are already set. If so, it won't try to do it again. This is done with the following command:
getfacl --absolute-names --tabular #{dir} | grep #{webserver_user}.*rwx | wc -l"
Try to run this command manually (replace #{dir}
and #{webserver_user}
with the actual values) to see the outcome. If it yields no results, then Capifony assumes the permissions have not yet been set, and will try to do so.
In that case, manually check the permissions with getfacl
. If they are indeed incorrect, manually set them (again, replace #{user}
, #{webserver_user}
and #{dir}
) using "the power of root":
sudo setfacl -R -m u:#{user}:rwX -m u:#{webserver_user}:rwX #{dir}
sudo setfacl -dR -m u:#{user}:rwx -m u:#{webserver_user}:rwx #{dir}
Then run Capifony again. If all is well, it should succeed this time!