Fixing World-writable MySql error in Docker
Solution 1
It seems solution for having files with not full permissions when using Windows host is sharing files with "intermediate directory" and then copy those files into desired directory in Docker container.
In above case (MySQL container) it could be done like this (you can use this method also in other cases)
Dockerfile:
# Base image
FROM mysql:5.7
# Copy starting scripts file
COPY start.sh /root/start.sh
# Run necessary services
CMD ["/bin/bash", "/root/start.sh"]
docker-compose.yml (showed only db container)
db:
build: ../builds/mysql-5.7
environment:
- MYSQL_ROOT_PASSWORD=pass
- MYSQL_DATABASE=
- MYSQL_USER=
- MYSQL_PASSWORD=
expose:
- 3306
volumes:
- /c/Users/marcin/dock-test/composers/l1.app/mysql/data/:/var/lib/mysql/
- /c/Users/marcin/dock-test/composers/l1.app/mysql/conf.d/:/etc/mysql/conf.d/source
- /c/Users/marcin/dock-test/composers/l1.app/mysql/log/:/var/log/mysql/
Plese notice that above we mount conf.d directory to /etc/mysql/conf.d/source
directory and not to /etc/mysql/conf.d/
directory (so MySql won't load this file for now).
start.sh
#!/bin/sh
cp /etc/mysql/conf.d/source/* /etc/mysql/conf.d/
/entrypoint.sh mysqld
Above we copy now all files from conf.d/source
directly into conf.d
- those files are not shared with Windows host so they will be created with Linux permissions (in my case leaving defaults - without using chmod is fine).
To verify whether custom mysql configuration values are loaded now I run:
mysql -u root -p
and type my password.
When I type SHOW VARIABLES;
I will see some settings from my.cnf
that previously (without putting this file had different values), so it's working as expected.
Of course drawback of this solution is that those files won't be really shared so in case those files would be changed in Docker machine, they won't be updated in Windows host, but in above case when we want to use custom config files it doesn't make any difference and solve the issue.
Solution 2
I just encountered this issue and the fix for me is just to set my.cnf
file to read-only in Windows.
Solution 3
This works for me
mysql:
networks:
- main
image: library/mysql:5.7
container_name: 'mysql'
command: >
bash -c "
chmod 644 /etc/mysql/conf.d/*.cnf
&& /entrypoint.sh mysqld
"
ports:
- "3308:3308"
volumes:
- ./my_local_dir/var/lib/mysql:/var/lib/mysql
- ./my_local_dir/etc/mysql/conf.d/:/etc/mysql/conf.d/
restart: always
environment:
MYSQL_ROOT_PASSWORD: 'root'
MYSQL_DATABASE: 'some'
Solution 4
I have an alternative answer for those that just need to set a few configuration options.
In the docker compose file you can do something like this.
db:
image: mysql
command: >
bash -c "mysqld --user=root --group_concat_max_len=1844674407370954752"
environment:
- MYSQL_ROOT_PASSWORD=pass
- MYSQL_DATABASE=
- MYSQL_USER=
- MYSQL_PASSWORD=
expose:
- 3306
Notice I run mysqld and then set the options --group_concat_max_len as an example. If you need more options just add more -- within the "" with the name of the option. This is an elegant solution that does not require making a new image from the default mysql one.
What command does in a docker compose file is overwrites the default CMD command in the image. The images default command simply runs mysqld (you can look it up on their github page), so I simply just run it as well but give it some parameters to pass in. Refer to the very last line of this file to see the CMD command. (refer to this: https://github.com/docker-library/mysql/blob/master/5.5/Dockerfile)
Using this method you do not even need to worry about voluming in a mysql configuration file, which for me was a big issue since it had to be 777 to work when doing docker-compose up but would then proceed to fail due to the world writable problem.
Solution 5
Thanks to @marcin-nabiałek for the inspiration, I got this solution working without having to write a custom script to run commands as I was still ending up with permissions issues. The script contents could've been completed with the Dockerfile commands (see mariadb/Dockerfile
contents below).
I run docker-compose -p my_project up --build -d
in the project-root
directory.
File structure is as follows. project-root
:
drwxr-xr-x 1 cmeza 197121 0 Aug 22 16:19 .git/
-rw-r--r-- 1 cmeza 197121 40 Aug 22 15:41 .gitignore
-rw-r--r-- 1 cmeza 197121 1056 Aug 22 13:24 Dockerfile
-rw-r--r-- 1 cmeza 197121 291 Aug 22 13:24 PROJECT.md
-rw-r--r-- 1 cmeza 197121 3642 Aug 22 13:24 README.md
drwxr-xr-x 1 cmeza 197121 0 Aug 22 13:24 bin/
-rw-r--r-- 1 cmeza 197121 944 Aug 22 15:42 docker-compose.yml
drwxr-xr-x 1 cmeza 197121 0 Aug 22 15:41 mariadb/
project-root/mariadb
:
-rw-r--r-- 1 cmeza 197121 193 Aug 22 15:46 Dockerfile
drwxrwxrwx 1 cmeza 197121 0 Aug 22 13:57 conf/
-rwxrwxrwx 1 cmeza 197121 5013 Aug 22 13:57 conf/my_custom.cnf
drwxrwxrwx 1 cmeza 197121 0 Aug 22 16:07 data/
-rwxrwxrwx 1 cmeza 197121 0 Aug 22 16:07 data/.gitignore
drwxrwxrwx 1 cmeza 197121 0 Aug 22 16:06 entrypoint/
-rwxrwxrwx 1 cmeza 197121 1163 Aug 22 16:06 entrypoint/default.sql
drwxrwxrwx 1 cmeza 197121 0 Aug 22 15:52 log/
-rwxrwxrwx 1 cmeza 197121 0 Aug 22 15:52 log/.gitignore
docker-compose.yml
(note the relative paths for the volumes):
(other services here)
db:
environment:
- MYSQL_ROOT_PASSWORD=my_super_secret_password
- MYSQL_DATABASE=my_db
ports:
- "3306:3306"
volumes:
- ./mariadb/entrypoint:/docker-entrypoint-initdb.d
- ./mariadb/conf:/etc/mysql/conf.d/my_conf_files
- ./mariadb/data:/var/lib/mysql
- ./mariadb/log:/var/log/mysql
build: ./mariadb
entrypoint:
- docker-entrypoint.sh
- mysqld
(some other services here)
mariadb/Dockerfile
:
# Base image
FROM mariadb:5.5
# Copy custom conf file(s)
# .\conf being your relative host path from this Dockerfile
# \etc\mysql\conf.d\ being the VM path
COPY .\conf\* \etc\mysql\conf.d\
# Make the conf files not writeable so mysql will read them
RUN chmod a-w \etc\mysql\conf.d\*
This got me everything I needed & I still have some hair left on my head. Let me know if this helps anyone else.
Marcin Nabiałek
I'm a Cerified Laravel Developer & Zend Certified PHP Engineer experienced in making code reviews. If you need remote Laravel PHP developer or you are looking for someone to help you to keep high code quality, feel free to contact. Learn more about me at Marcin Nabiałek - Laravel PHP developer
Updated on June 03, 2022Comments
-
Marcin Nabiałek almost 2 years
I'm using docker-compose, for db I have such container defined:
db: build: ../builds/mysql-5.7 environment: - MYSQL_ROOT_PASSWORD=pass - MYSQL_DATABASE= - MYSQL_USER= - MYSQL_PASSWORD= expose: - 3306 volumes: - /c/Users/marcin/dock-test/composers/l1.app/mysql/data/:/var/lib/mysql/ - /c/Users/marcin/dock-test/composers/l1.app/mysql/conf.d/:/etc/mysql/conf.d/ - /c/Users/marcin/dock-test/composers/l1.app/mysql/log/:/var/log/mysql/
My Dockerfile for this image is:
# Base image FROM mysql:5.7 # Set valid file permissions - otherwise MySql won't read those files #COPY mysql-perm-fix.sh /etc/init.d/mysql-perm-fix.sh #RUN chmod +x /etc/init.d/mysql-perm-fix.sh #RUN update-rc.d mysql-perm-fix.sh defaults 100 #RUN mkdir /etc/mysql/conf.d/source #RUN cp /etc/mysql/conf.d/source/my.cnf /etc/mysql/conf.d/my.cnf #RUN chmod -R 644 /etc/mysql/conf.d
At the moment everything is commented except base MySql image.
The problem is, when I start my containers, my MySql cnf file won't be used by MySql because of this warning:
mysqld: [Warning] World-writable config file '/etc/mysql/conf.d/my.cnf' is ignored.
I'm using Windows as my host system. The problem is that Docker mounts diretory with full permissions and they couldn't be changed.
The question - how could it be solved? As you see in my Dockerfile I've tried a few solutions, but none of them works for me (but maybe I'm doing something wrong).
At the moment I think the most reasonable solution would be mounting MySql conf files not directly into
/etc/mysql/conf.d/
but into some other directory and copy those files to/etc/mysql/conf.d/
directory before MySql starts and set them not 777 permissions. I've tried it, but in Dockerfile those files are not present yet so they cannot be copied.Is there any easy solution to fix it? Or maybe some MySql settings could be changed to don't care about conf file permissions?
I also cannot simple use COPY inside Dockerfile to copy Mysql config files (instead of using volumes) because I want to use those images by multiple sites and each of them might have different configuration.
-
Marcin Nabiałek about 8 yearsThe problem is that I don't want to share those volumes between containers at all. I just want to include into container cnf files i have in my host system (Windows) into MySql container.
-
Ken Cochrane about 8 yearsOk, I included another option in the answer for not sharing between containers, but that wouldn't pull from the host. I'll see if I can think of something else.
-
Marcin Nabiałek about 8 yearsThank you for your effort. It seems I've managed to solve this (see my answer)
-
Tarmo over 5 yearsThis should be the accepted answer really now. 1 checkbox instead of building a new image
-
Aldo Inácio da Silva about 3 yearsI just give less permission to the file my.cnf
chmod 0444 my.cnf
and it worked. If I give all permissionschmod 777 my.cnf
it doesn't work. -
hpca01 almost 3 yearsYOU sir are the REAL MVP.
-
izogfif about 2 yearsThe issue is that there is no way to mark the file as read-only in git commit :(