Issue type: Docker, bind mounts/volumes
OS Version/build: Linux 5.3.0-59-generic #53~18.04.1-Ubuntu SMP Thu Jun 4 14:58:26 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
App version: Docker version 19.03.8, build afacb8b7f0
Image:
REPOSITORY TAG IMAGE ID CREATED SIZE
mariadb 10.5 af16a2dc06bd 6 weeks ago 365MB
I tried creating a container with a mariadb:10.5
image and bind mount for my configuration files.
Here’s the command:
sudo docker run -d --name database-mariadb1 \
-e MYSQL_ROOT_PASSWORD=XXX \
-p 9270:3306 \
-v "/opt/example/database/mariadb/mysql:/etc/mysql/" \
mariadb:10.5
The /opt/example/database/mariadb/mysql
directory is empty, but when I tried creating a container without the bind mount, configuration files are created just fine.
I have NGINX, PHP, Certbot and SRCDS running under similar configurations (though they’re using docker-compose, but the same thing was happening when I tried to launch a mariadb container with it).
I tried just mounting the my.cnf
configuration file like in MariaDB’s DockerHub page example, in a section “Using a custom MySQL configuration file”,
docker run --name some-mariadb -v /my/custom:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mariadb:tag
but it kept creating a folder named my.cnf
instead.
Also, after a container had been initialized and was running. I tried executing bash
on the container and looking in the folder where the configuration files were supposed to be at, but they weren’t inside the container too.
Any help appreciated!
I’m a bit confused now, let me explain.
As a temporary workaround for configuration files, I copied generated configuration files from a container without directories bound. This was later confirmed working by allowing general logs in these configuration files after binding the directory back and seeing them mentioned in logs provided by docker logs
command. Though after trying to bind /var/log/mysql
directory, an error appeared, but I can’t reproduce it (it was File permission denied: 13
or something similar).
First I tried adding write permissions to user, group and others using chmod
to the bound directory, but that didn’t work.
I decided to remove a container, create an empty file named mysql.log
in the bound directory on my host and see if that would work and it did, the error disappeared.
Now here’s why I can’t reproduce the error. After the previous solution worked, I wanted to share it here and I tried to reproduce that error, but after I removed the container (including volumes, like always), deleted the file and started the container. There wasn’t any error when searching for it using docker logs
and to my suprise, the file has appeared by itself and was working fine! I tried deleting it again and restarting the container, but it kept appearing like normal.
What’s happening?
It probably works for mysql.log
, but what if, for example another image wants to create many files, doing that for every single one and if there wouldn’t be any bash
a/o ls
or similar commands. It would take forever.
I would assume the same could’ve worked for configuration files also.
The original issue is still present and I would like to know a solution for both issues, just in case.
Howdy…
I have fought something similar to this when creating my docker image for www.harperdb.io.
I suspect a permissions issue on the host.
who is the user running the docker command?
and who is the owner of the directories on the host?
Iff they are the same owners, is the owner root?
try this command on host and container:
id -u <username>
I think there is some type of User ID conflict in the container, probably user id 1001, and your host user id, iff root is 0.
I do not believe the container will have permission to write/read to your host.
Try chown and not chmod on your host.
One of the workarounds I did at some point was -v bind-mount then copy the files into the host directory.
But my issue was the opposite direction, I wanted users to persist data on the host, so I copy HarperDB container database configs into the host bind-mount directory.
Ill be curious to see iff the user id directory owner ship helps.
[EDIT]
After digging through some other posts,
some people use user groups to help manage file permissions.
the command: id
returns all the groups your users are apart of.
for my local user the command returns:
uid=1000(ubuntu) gid=1000(ubuntu) groups=1000(ubuntu),4(adm),20(dialout),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),108(lxd),114(netdev)
Check the container user and groups.
Then chown the host directories to a group ID that matches the container GID.
Maybe?
good luck
1 Like
I am running the docker command as root.
Root is the owner of all the directories.
Both on the container and host id -u root
returns 0.
I found something interesting though.
After doing stat command on the mysql.log
file, on my host, it turned out it’s Uid
and Gid
are 999, which is “lxd”. I never changed it to that and I forgot to mention that I’m running another database using lxd, which I wanted to get rid of after moving completely to Docker and I never thought it could interfere with Docker, at least not in that way. I’ll dig a bit more, weird that I haven’t thought about checking that sooner.
EDIT: Sorry, but I was mistaken. Both Uid
and Gid
are 999 on host and container, but on host the name is lxd
, which I guess is just a left-over user/group from lxd, but on container it’s mysql
, which I guess is a user/group that has been created. Now I don’t think I can just make the service use root.
Alright I got it working! Here’s what happened.
I tried setting…
user 0
(named root
on both, host and container) for the directory on my host
user 999
(named lxd
on host and mysql
on container) for the directory on my host
Both didn’t work.
I saw that there was a message “Switching to dedicated user ‘mysql’”, so I thought changing the user to root
would allow to bypass these permission barriers,
so inside my.cnf
, under [mysqld]
I added user = root
, so it looked like
[mysqld]
user = root
but that didn’t work also.
Later I learned that by accident (Confirmed thanks to https://unix.stackexchange.com/a/303503/264280) that you can’t use commands like cd
to get into a directory that doesn’t allow execute (x) permission for your user.
So I allowed it for each class, but that didn’t work.
After that I also found out that MariaDB automatically changes user to mysql
if the user that executed the entrypoint was root
. Which can be found here.
First I thought to remove that check, but then I thought about changing the user which would be easier and work as intended.
And it finally worked!
Changing all permissions for a directory using chmod
to 777 (rwxrwxrwx).
Changing the owner user and group to a custom one using chown user:group -R ./directory
.
Setting --user user:group
option in a docker run command.
Last two mentioned above were suggested by this article, which mentioned my exact issue.
I need to confirm it and experiment with it.
I really don’t want to give all permissions to a folder and I want do other things a bit differently,
but at least a file permission (code: 13) error disappeared when binding /var/lib/mysql
like mentioned here.
just as i suspected.
Tracking down when a user changes is probably pretty hard…
I would suggest to run your docker commands as a non root user.
Good work on tracking it down.
And Thank you for posting up the solution in this very thorough post.
Your diligence is appreciated.