Symfony2 Capifony deploy setfacl Operation not per

2019-07-05 13:41发布

问题:

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

回答1:

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!



回答2:

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.