I'm developing a Wordpress theme, and want to use Docker in my dev setup. What I've done is pretty simple:
- create a
database
service running MySQL 5.7 - create a
wordpress
service, where I mount my theme folder as a volume into/var/www/html/wp-content/themes
I'm struggling with the volume permissions, however.
I'm working with the following project folder structure:
.
├── docker-compose.yml
└── my-theme
My docker-compose.yml
file looks like this:
version: '3.2'
services:
database:
image: mysql:5.7
volumes:
- my_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: root
wordpress:
depends_on:
- database
image: wordpress:php7.3-apache
ports:
- '8000:80'
restart: always
environment:
WORDPRESS_DB_HOST: database:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: root
working_dir: /var/www/html
volumes:
- type: volume
source: ./my-theme
target: /var/www/html/wp-content/themes/my-theme
volumes:
my_data: {}
When I run docker-compose up
, everything works as expected: containers are created, and I can access Wordpress in the browser. However, the theme I mounted as a volume doesn't render anything when I activate it.
When I sh
into the wordpress
container (docker-compose exec wordpress sh
) I can see that the wp-content/themes
folder is owned by root
. So I figured that was the problem.
I verified this being a permissions issue by manually and recursively chown
ing the wp-content
folder in the container:
chown -R www-data:www-data /var/www/html/wp-content
Once that was done, my theme rendered as expected. So now I'm looking for a way to avoid this chown
process (the idea is that any other dev can clone this project, simply run docker-compose up
and start working).
The first thing I tried was to make a Dockerfile where I would build a slightly customized Wordpress image:
FROM wordpress:php7.3-apache
RUN mkdir -p /var/www/html/wp-content/themes/test-theme \
&& chown -R /var/www/html/wp-content
My reasoning behind this was that by creating the directory and chown
ing it beforehand, the volume would inherit the user:group mapping. Alas, no such thing; mounting the volume overrides this mapping and sets it back to root:root
.
After that, I tried to set the APACHE_RUN_USER
and APACHE_RUN_GROUP
environment variables in my docker-compose.yml
file:
version: '3.2'
services:
database:
...
wordpress:
...
environment:
WORDPRESS_DB_HOST: database:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: root
APACHE_RUN_USER: '$(id -u)'
APACHE_RUN_GROUP: '$(id -g)'
working_dir: /var/www/html
volumes:
- type: volume
source: ./my-theme
target: /var/www/html/wp-content/themes/my-theme
volumes:
my_data: {}
However, this threw a bunch of apache errors on build.
I'm at a bit of a loss here now. Is there any best practice for managing permissions of mounted volumes in Docker? I've googled a lot for this, but the solutions I do find go a little bit over my head.
'$(id -u)'
to be wrong, as Shell variables are not evaluated between single quotes, although I'm not sure this applies here. Other than that, doingchown
in your Dockerfile is totally legit (here is a GitHub issue discussing this problem.) – Harquebusierchown
in Dockerfile would do the trick (based on same GH issue you linked), but it seems that once I mount a volume, the permissions are overridden and set back to root:root. I tested by doingdocker-compose up
with and withoutvolumes
key in wordpress service. When I sh into the container without mounted volume,ls -l
showswww-data:www-data
for wp-content folder. Once I mount the volume,ls -l
showsroot:root
... – Conversazione