File ownership on docker named volumes - wordpress

I'm having a folder ownership issue when I try to run WordPress on Docker containers. Folders like wp-content and themes are owned by root, not allowing me to install themes and plugins from the web interface.
Goals
Run WordPress on Docker.
Obtain a theme from a git repo (owned by us).
Be able to run WP-CLI from its official Docker image (wordpress:cli).
Be able to install themes and plugins from the web interface.
Have all files and folders under /var/www/html be owned by www-data (uid 33).
Specs
Docker version 18.09.5, build e8ff056
docker-compose version 1.24.0, build 0aa59064
single container instances for each service - no kubernetes, swarm, stack, etc.
My docker-compose.yml
My dockerfile (copied from the git repo):
FROM wordpress:5
COPY --chown=33 ./ /var/www/html/wp-content/themes/theme/
Volumes
I don't declare volumes on my dockerfile -- it's only those two lines above, nothing else. In fact, this image exists only to copy a folder into the WordPress image. The WordPress image (which my image derives from) declares a volume in its dockerfile, though.
I do declare volumes on my docker-compose file but when omitting them the issue persists
Results
File and folder ownerships...
when using a custom image with named volumes
when using a custom image without named volumes
when using the default image with named volumes
when using the default without named volumes
UPDATE
There's some issue going on with the COPY step on the Docker build, but I can't figure out what.
I changed my dockerfile to
FROM alpine
COPY ./ /var/www/html/wp-content/themes/theme/
RUN chown -R 33:33 /var/www/html
RUN ls -n /var/www/html
If I build from alpine, uid 33 is the owner:
Step 4/4 : RUN ls -n /var/www/html
---> Running in e9850fa85800
total 4
drwxr-xr-x 1 33 33 4096 Apr 12 19:34 wp-content
I change the first line to FROM wordpress, now root is the owner:
Step 4/4 : RUN ls -n /var/www/html
---> Running in 2810cc37aaba
total 4
drwxr-xr-x. 3 0 0 4096 Apr 12 19:38 wp-content
How do I proceed to obtain the results that I want (that is, the theme files on /var/www/html/wp-content/themes/theme/ and all files and folders owned by www-data (uid 33))?

you can set owner using ADD or COPY command in dockerfile, for your COPY command, try COPY --chown:www-data:www-data ./ /var/www/html/wp-content/themes/theme/.

Related

Duplicator folder permissions Linux

I am trying to migrate a WordPress site using the Duplicator plugin. I have created an ec2 instance on AWS, installed Apache and copied over the files from the Duplicator backup to /var/www/html/.
When I visit the site on the browser going to myip/dup-installer/main.installer.php I get the following error:
My www folder permissions are : drwxrwxrwx 3 root www-data 4096.
My html folder permissions are: drwxrwxrwx 7 www-data www-data 4096.
My dup-installer folder permissions are: drwxrwxrwx 8 www-data www-data 4096.
And finally, my main.installer.php file permissions are: -rw-rw-r-- 1 www-data www-data 20437.
It all looks correct but I don't understand why I'm getting the error when I visit the installer. Is there something wrong with my permissions?
Currently, your permissions are fully open on your www directory. That shouldn't be like that, most files should not be world writable.
you should change this to 755 via this command:
sudo chmod -R 755 /var/www
Note, use the correct path to your www directory if it isn't correct for you.
regarding your missing CSRF (Cross-Site Request Forgery) file, this is probably because your copy didn't have the correct priv to copy it. Might look on the original server to see if you can grab it and move it over.
It turns out I had to execute [website-hush-information]_installer-backup.php which sits one level before the dup-installer folder.
I was trying to execute the main.installer.php inside dup-installer based on previous experience with this plugin, but in this version, this was not needed.
Thanks for the help #JP-LISN, it pointed me in to the correct direction by the process of elimination.

WSL + Docker file permission issues

I'm using docker-compose in a WSL environment. Currently Wordpress runs in the docker composer. All files in the Projects folder are at www-data group and user which allows Wordpress to create everything and upload plugins.
But vs-code has file permission errors as soon as I want to edit files.
Switching user to and www-data groups allows vs-code to edit files but Wordpress has permission errors when uploading plugins or deleting plugins/files.
wsl.conf looks like that:
# Enable extra metadata options by default
[automount]
enabled = true
root = /windir/
options = "metadata,umask=22,fmask=11"
mountFsTab = false
# Enable DNS – even though these are turned on by default, we'll specify
here just to be explicit.
[network]
generateHosts = true
generateResolvConf = true
Using Win 11 with Ubuntu-20.04 - Kernel: 5.10.60.1 and latest docker version.
EDIT:
Still, when I want to edit stuff in Wordpress, upload Media or uploading plugins I need to sudo chown -R www-data * and if I want tot edit files in VScode I need to sudo chown -R <username> *
I had a similar issue on my local WordPress development setup. (Windows 10 + WSL2), here is a link to the git repo:
https://github.com/dorumarginean/wordpress-docker
For uploading images / plugins I updated the owner like you mentioned and for write permissions with Visual Studio Code I edited the PHP container inside my docker-compose.yml.
user: “1000:1000”
Here's what I did when I had a similar problem:
create a new group that contains both www-data and the user that runs your editor.
Let's call your local user myuser and your new group mygroup for now.
First you need to create a new group
sudo addgroup mygroup
Add both the webserver user and your user to this new group
sudo adduser myuser mygroup
sudo adduser www-data mygroup
now give the ownership of the website directory to this new group. cd to your website's directory, then
sudo chown -vR :mygroup .
grant write permission to the group
sudo chmod -vR g+w .
Check to make sure that the changes took effect with ls -ld to see the owner and the permissions of the files and groups myuser www-data to see if both users are indeed in mygroup.
Then make sure to reinitialize the user environment so the permissions coming from the new group will be updated
newgrp - mygroup
You may need to log out and log in again for the user environment to update in the GUI.

Amazon EFS: Changing Wordpress upload directory to outside root

I have multiple AWS EC2 instances which are updated from a Git repository via CodeDeploy. However, since keeping the wp-content/uploads folder in Git is messy and hard to maintain, I'm instead trying to move all uploads to a directory which I have mounted as an EFS filesystem. That way I should be able to share the uploads between multiple EC2 instances.
However, now I'm running into a new problem; there's no way for me to set the WP uploads folder to be outside of the WP root.
WordPress is located at /opt/bitnami/apps/wordpress/htdocs, which is also where our domain points. The EFS system is mounted to /home/bitnami/efs. Since the EFS directory is located outside of the WP root there's no way for me to link to it.
I have gotten this to work using a symlink directing the default wp-content/uploads folder to my desired path; however, this doesn't really solve my issue since I can't rely on the symlink to not be overwritten during CodeDeploy deployments.
So my questions are as follows:
Is it possible to have this setup work without using a symlink, so I can make deployments without worrying about by uploads being affected?
If a symlink is the only/best way to make this work, is there any way to add the symlink to the git repository, or any other way to make absolutely sure it persists during CodeDeploy deployments?
You can directly mount your EFS to /opt/bitnami/apps/wordpress/htdocs/wp-content/uploads to avoid symlinks.
In your appspec.yml add two hooks:
hooks:
BeforeInstall:
- location: /deploy/BeforeInstall.sh
timeout: 3000
runas: root
AfterInstall:
- location: /deploy/AfterInstall.sh
timeout: 3000
runas: root
Then create directory deploy and two files in it BeforeInstall.sh and AfterInstall.sh
BeforeInstall.sh unmount the EFS if its mounted
#!/bin/bash
if mount | grep /opt/bitnami/apps/wordpress/htdocs/wp-content/uploads > /dev/null; then
sudo umount /opt/bitnami/apps/wordpress/htdocs/wp-content/uploads
fi
Then mount EFS again via AfterInstall.sh after deployment
#!/bin/bash
sudo mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2 fs-fxxxxxx.efs.us-west-2.amazonaws.com:/ /opt/bitnami/apps/wordpress/htdocs/wp-content/uploads
Note: You can also mount entire wp-contents directory, not just uploads folder, so that update in themes and plugins also get reflected in other EC2s automatically.
Also, symlink is a better solution, so you don't have to ever worry about accidentally removing the EFS mount during deployment if umount ever fails. You can just recreate symlink again after deployment using AfterInstall hook and add code in file AfterInstall.sh
#!/bin/bash
ln -s /home/bitnami/efs /opt/bitnami/apps/wordpress/htdocs/wp-content/uploads

Docker recreates directories on host after reboot

I created some containers on my system (ubuntu 14.04) using docker-compose which mounted directories from the host into the containers.
Now, every time I reboot the host, these directories are recreated, even though the containers do not longer exist (and I therefore deleted the directory).
Example:
I had a container for gitlab-ci in
/var/docker/gitlab-ci/
Containing the files/directories
docker-compose.yml
data/
postegresql/
I have deleted the directory
gitlab-ci/
now,
gitlab-ci/data
gitlab-ci/postgresql
are created after every reboot.
How do I get rid of them?
Those containers might still exists. What does the docker ps -a command shows?
If you can still see your gitlab related containers, remove them with docker rm -f <container name>, then delete the directories and reboot to check if they appear again.
If you still have your docker-compose.yml file, then you could have removed those containers with:
docker-compose stop
docker-compose rm

How to mount a directory in the docker container to the host?

It's quite easy to mount a host directory in the docker container.
But I need the other way around.
I use a docker container as a development environment for developing WordPress plugins. This docker container contains everything needed to run WordPress (MySQL, Apache, PHP and WordPress). I mount my plugin src folder from the host in the docker container, so that I can test my plugin during development.
For debugging it would be helpful if my IDE running on the host has read access to the WordPress files in the docker container.
I found two ways to solve the problem but both seem really hacky.
Adding a data volume to the docker container, with the path to the WordPress files
docker run ... -v /usr/share/wordpress/ ...
Docker adds this directory to the path on the host /var/lib/docker/vfs/dir... But you need to look up the actual path with docker inspect and you need root access rights to see the files.
Mounting a host directory to the docker container and copying the WordPress files in the container to that mounted host directory. A symlink doesn't seem to work.
Is there a better way to do that? Without copying files or changing access rights?
Thank you!
Copying the WordPress files to the mounted folder was the solution.
I move the files in the container from the original folder to the mounted folder and use symbolic links to link them back to the original folder.
The important part is, the container can follow symbolic links in the container and but the host can't. So just using symbolic links from the original folder to the mounted folder doesn't work, because the host cannot follow symbolic links in the container!
You can share the files using smb with svendowideits samba container like this:
docker run --rm -v $(which docker):/docker -v /var/run/docker.sock:/docker.sock svendowideit/samba <container name>
It's possible to do if you use volume instead of filesystem path. It's created for you automatically, if it already doesn't exist.
docker run -d -v usr_share_wordpress:/usr/share/wordpress --name your_container ... image
After you stop or remove your container, your volume will be stored on your filesystem with files from container.
You can inspect volume content during lifetime of your_container with busybox image. Something like:
docker run -it --rm --volumes-from your_container busybox sh
After shutdown of your_container you can still check volume with:
docker run -it --rm -v usr_share_wordpress:/usr/share/wordpress busybox sh
List volumes with docker volume ls.
I had a similar need of exposing the files from container to the host. There is an open issue on this as of today. One of the work-arounds mentioned, using binds, is pretty neat; it works when the container is up and running:
container_root=$(docker inspect --format {{.State.Pid}} "$container_name")/root
sudo bindfs --map=root/"$USER" "$container_root/$app_folder" "$host_folder"
PS: I am not sure this is good for production, but it should work in development scenarios!
Why not just do: docker run ... -v /usr/share/wordpress/:/usr/share/wordpress. Now your local /usr/share/wordpress/ is mapped to /usr/share/wordpress in the Docker container and both have the same files. You could also mount elsewhere in the container this way. The syntax is host_path:container_path, so if you wanted to mount /usr/share/wordpress from your host to /my/new/path on the container, you'd just do: docker run ... -v /usr/share/wordpress/:/my/new/path.

Resources