I had the same problem on a rocky linux box. Unfortunately I was not able to solve it by reverting to a previous version of docker, so I had to dig a bit.
As my borgmatic backup failed as well and borgmatic is a lot more verbose, I was able to pinpoint the problem to access of socket files in container-volumes if selinux is enabled. It looks like somehow selinux got into the mix here. For now, mailcow is using the mysqld socket in “mysql-socket-vol” volume. For some reason, I do not fully understand yet, it is not longer possible for other containers to access the “mysql-socket-vol” although it gets mounted correctly. But as soon as the container apps try to access it, selinux will deny access and a wild “permission denied” appears. After switching selinux into permissive mode, everything worked again. This confirmed my theory about SELinux. In the quest of finding some valuable information about the issue, i found a nice blog article from RedHat (which is the base for rocky): https://www.redhat.com/en/blog/why-you-should-be-using-multi-category-security-your-linux-containers
This explains quite well, why the problem happens. So sum it up:
Each container gets its own security labels (MCS/MLS labels) and by default SELinux prevents any access to socket_files created by other containers. From a file type perspective SELinux allows the access to the socket because container_t and container_file_t have a corresponding access vector rule. From a security label perspective, SELinux (or the MCS/MLS part) will deny access to it.
So thats for the cause, but how do I allow access to the socket without disabling SELinux as a security boundary?
Edit for the sake of being a completionist:
Here’s the actual output of the SELinux audit:
[root@mail mailcow-dockerized]# ausearch -m avc -ts recent | audit2why
type=AVC msg=audit(1746602018.224:4302790): avc: denied { write } for pid=319379 comm="check_mysql" name="mysqld.sock" dev="dm-8" ino=541152109 scontext=system_u:system_r:container_t:s0:c97,c180 tcontext=system_u:object_r:container_file_t:s0:c400,c869 tclass=sock_file permissive=1
Was caused by:
#Constraint rule:
# mlsconstrain sock_file { ioctl read getattr } ((h1 dom h2 -Fail-) or (t1 != mcs_constrained_type -Fail-) ); Constraint DENIED
mlsconstrain sock_file { write setattr } ((h1 dom h2 -Fail-) or (t1 != mcs_constrained_type -Fail-) ); Constraint DENIED
mlsconstrain sock_file { relabelfrom } ((h1 dom h2 -Fail-) or (t1 != mcs_constrained_type -Fail-) ); Constraint DENIED
mlsconstrain sock_file { create relabelto } ((h1 dom h2 -Fail-) or (t1 != mcs_constrained_type -Fail-) ); Constraint DENIED
# Possible cause is the source level (s0:c97,c180) and target level (s0:c400,c869) are different.