I am deploying my Symfony2 web app onto an Apache web server, on an Ubuntu machine, hosted on AWS, using Capifony multistage deploy.
I have user set
set :user, "ubuntu"
And writable directory for cache set like so
set :writable_dirs, ["app/cache"]
set :webserver_user, "www-data"
set :use_set_permissions, true
set :permission_method, :acl
Everything is deploying fine apart from when this is run
executing "setfacl -R -m u:ubuntu:rwx -m u:www-data:rwx /var/www/releases/20140310012814/app/cache"
I get multiple Operation not permitted errors such as
setfacl: /var/www/releases/20140310012814/app/cache/prod/classes.php: Operation not permitted
It seems that the user, presumably 'www-data', cannot set permissions on files created by 'ubuntu'. However, I have run the following on the server from the /var/www/current directory, but I'm not entirely sure what they do:
sudo setfacl -R -m u:www-data:rwX -m u:`whoami`:rwX app/cache
sudo setfacl -dR -m u:www-data:rwx -m u:`whoami`:rwx app/cache
Here is some acl info
getfacl app/cache
# file: app/cache
# owner: ubuntu
# group: ubuntu
user::rwx
user:www-data:rwx
user:ubuntu:rwx
group::rwx
mask::rwx
other::rwx
default:user::rwx
default:user:www-data:rwx
default:user:ubuntu:rwx
default:group::rwx
default:mask::rwx
default:other::rwx
I have had a look at a similar issue here Should I run something similar? such as:
sudo sh -c 'setfacl -R -m u:ubuntu:rwX -m u:www-data:rwX /var/www/current/app/cache'
Thanks
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!
You have run the sudo setfacl
on the current directory, but you are receiving the errors on the single releases folders. Anyway, www-data should be the right owner of the cache folder, it is the main user of that dir, in the end!
In our deploy script, we use this:
set :permission_method, :acl
set :writable_dirs, ["app/cache"]
set :webserver_user, "www-data"
set :use_set_permissions, false
set :use_sudo, false
I think this is the right solution.