Docker Community Forums

Share and learn in the Docker community.

MariaDB doesn’t create configuration files when sharing a directory using volumes

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.

docker create -v //c/Users/docker-workspace/mariadb-data-dir:/var/lib/mysql --name docker-mariadb-data hello-world

MINGW64 ~
$ docker inspect docker-mariadb-data
[
{
“Id”: “eff843a06bbe4b5cfb575ca095572d4dba735ce3e4ddd84ffa02a8bb7ae2ba76”,
“Created”: “2016-01-28T04:44:09.997407335Z”,
“Path”: “/hello”,
“Args”: ,
“State”: {
“Status”: “created”,
“Running”: false,
“Paused”: false,
“Restarting”: false,
“OOMKilled”: false,
“Dead”: false,
“Pid”: 0,
“ExitCode”: 0,
“Error”: “”,
“StartedAt”: “0001-01-01T00:00:00Z”,
“FinishedAt”: “0001-01-01T00:00:00Z”
},
“Image”: “0a6ba66e537a53a5ea94f7c6a99c534c6adb12e3ed09326d4bf3b38f7c3ba4e7”,
“ResolvConfPath”: “”,
“HostnamePath”: “”,
“HostsPath”: “”,
“LogPath”: “”,
“Name”: “/docker-mariadb-data”,
“RestartCount”: 0,
“Driver”: “aufs”,
“ExecDriver”: “native-0.2”,
“MountLabel”: “”,
“ProcessLabel”: “”,
“AppArmorProfile”: “”,
“ExecIDs”: null,
“HostConfig”: {
“Binds”: [
“//c/Users/docker-workspace/mariadb-data-dir:/var/lib/mysql”
],
“ContainerIDFile”: “”,
“LxcConf”: ,
“Memory”: 0,
“MemoryReservation”: 0,
“MemorySwap”: 0,
“KernelMemory”: 0,
“CpuShares”: 0,
“CpuPeriod”: 0,
“CpusetCpus”: “”,
“CpusetMems”: “”,
“CpuQuota”: 0,
“BlkioWeight”: 0,
“OomKillDisable”: false,
“MemorySwappiness”: -1,
“Privileged”: false,
“PortBindings”: {},
“Links”: null,
“PublishAllPorts”: false,
“Dns”: null,
“DnsOptions”: null,
“DnsSearch”: null,
“ExtraHosts”: null,
“VolumesFrom”: null,
“Devices”: ,
“NetworkMode”: “default”,
“IpcMode”: “”,
“PidMode”: “”,
“UTSMode”: “”,
“CapAdd”: null,
“CapDrop”: null,
“GroupAdd”: null,
“RestartPolicy”: {
“Name”: “no”,
“MaximumRetryCount”: 0
},
“SecurityOpt”: null,
“ReadonlyRootfs”: false,
“Ulimits”: null,
“LogConfig”: {
“Type”: “json-file”,
“Config”: {}
},
“CgroupParent”: “”,
“ConsoleSize”: [
0,
0
],
“VolumeDriver”: “”
},
“GraphDriver”: {
“Name”: “aufs”,
“Data”: null
},
“Mounts”: [
{
“Source”: “/c/Users/docker-workspace/mariadb-data-dir”,
“Destination”: “/var/lib/mysql”,
“Mode”: “”,
“RW”: true
}
],
“Config”: {
“Hostname”: “eff843a06bbe”,
“Domainname”: “”,
“User”: “”,
“AttachStdin”: false,
“AttachStdout”: true,
“AttachStderr”: true,
“Tty”: false,
“OpenStdin”: false,
“StdinOnce”: false,
“Env”: null,
“Cmd”: [
“/hello”
],
“Image”: “hello-world”,
“Volumes”: null,
“WorkingDir”: “”,
“Entrypoint”: null,
“OnBuild”: null,
“Labels”: {},
“StopSignal”: “15”
},
“NetworkSettings”: {
“Bridge”: “”,
“SandboxID”: “”,
“HairpinMode”: false,
“LinkLocalIPv6Address”: “”,
“LinkLocalIPv6PrefixLen”: 0,
“Ports”: null,
“SandboxKey”: “”,
“SecondaryIPAddresses”: null,
“SecondaryIPv6Addresses”: null,
“EndpointID”: “”,
“Gateway”: “”,
“GlobalIPv6Address”: “”,
“GlobalIPv6PrefixLen”: 0,
“IPAddress”: “”,
“IPPrefixLen”: 0,
“IPv6Gateway”: “”,
“MacAddress”: “”,
“Networks”: null
}

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.