在Docker中修复世界可写的MySql错误

Mar*_*łek 4 mysql file-permissions docker dockerfile docker-compose

我正在使用docker-compose,对于db,我定义了这样的容器:

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/
Run Code Online (Sandbox Code Playgroud)

该镜像的Dockerfile是:

# 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
Run Code Online (Sandbox Code Playgroud)

目前,除基本MySql映像外,所有内容均已注释。

问题是,当我启动容器时,由于以下警告,MySql不会使用MySql cnf文件:

mysqld:[警告]世界可写的配置文件'/etc/mysql/conf.d/my.cnf'被忽略。

我使用Windows作为主机系统。问题在于,Docker具有完全权限安装目录,并且无法更改它们。

问题-如何解决?正如您在Dockerfile中看到的那样,我尝试了一些解决方案,但是没有一个对我有用(但是也许我做错了)。

目前,我认为最合理的解决方案是将MySql conf文件不直接安装/etc/mysql/conf.d/到其他目录中,而是直接安装到其他目录中,/etc/mysql/conf.d/然后在MySql启动之前将这些文件复制到目录中,并将其设置为非777权限。我已经尝试过了,但是在Dockerfile中,这些文件尚不存在,因此无法复制。

有没有简单的解决方案可以解决?或者也许可以更改某些MySql设置以不关心conf文件的权限?

我也不能简单地在Dockerfile中使用COPY复制Mysql配置文件(而不是使用卷),因为我想通过多个站点使用这些映像,并且每个映像可能具有不同的配置。

Mar*_*łek 6

使用 Windows 主机时,文件没有完全权限的解决方案似乎是与“中间目录”共享文件,然后将这些文件复制到 Docker 容器中的所需目录中。

在上述情况(MySQL 容器)中,可以这样做(在其他情况下也可以使用此方法)

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"]
Run Code Online (Sandbox Code Playgroud)

docker-compose.yml(仅显示数据库容器)

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/
Run Code Online (Sandbox Code Playgroud)

请注意,上面我们将conf.d目录挂载到/etc/mysql/conf.d/source目录而​​不是/etc/mysql/conf.d/目录(因此MySql暂时不会加载该文件)。

启动文件

#!/bin/sh

cp /etc/mysql/conf.d/source/* /etc/mysql/conf.d/

/entrypoint.sh mysqld
Run Code Online (Sandbox Code Playgroud)

上面我们现在将所有文件conf.d/source直接复制到conf.d- 这些文件不与 Windows 主机共享,因此将使用 Linux 权限创建它们(在我的情况下保留默认值 - 不使用 chmod 就可以了)。

为了验证自定义 mysql 配置值是否已加载,我运行:

mysql -u root -p
Run Code Online (Sandbox Code Playgroud)

并输入我的密码。

当我输入时,SHOW VARIABLES;我会看到my.cnf之前的一些设置(没有将此文件放入不同的值),因此它按预期工作。

当然,这个解决方案的缺点是这些文件不会真正共享,所以如果这些文件在 Docker 机器中发生更改,它们不会在 Windows 主机中更新,但在上面的情况下,当我们想要使用自定义配置文件时它没有任何区别并解决问题。


小智 6

我刚遇到此问题,对我来说,解决方法是my.cnf在Windows 中将文件设置为只读。

  • 这应该是现在真正接受的答案。1 复选框而不是构建新图像 (5认同)
  • 我只是给文件 my.cnf `chmod 0444 my.cnf` 授予较少的权限,它就起作用了。如果我授予所有权限 `chmod 777 my.cnf` 它不起作用。 (2认同)
  • 问题是无法在 git commit 中将文件标记为只读:( (2认同)

Ned*_*udi 6

这对我有用

      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'

Run Code Online (Sandbox Code Playgroud)


Jos*_*han 5

对于那些只需要设置一些配置选项的人,我有一个替代答案

在 docker compose 文件中,您可以执行类似的操作。

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
Run Code Online (Sandbox Code Playgroud)

请注意,我运行 mysqld,然后设置选项--group_concat_max_len作为示例。如果您需要更多选项,只需在选项名称--中添加更多选项即可。""这是一种优雅的解决方案,不需要从默认的 mysql 镜像创建新镜像。

docker compose 文件中的命令会覆盖镜像中的默认CMD命令。images 默认命令只是运行mysqld(你可以在他们的 github 页面上查找它),所以我也只是运行它,但给它一些要传入的参数。请参阅此文件的最后一行以查看 CMD 命令。(参考这个:https://github.com/docker-library/mysql/blob/master/5.5/Dockerfile

使用这种方法,你甚至不需要担心 mysql 配置文件中的卷,这对我来说是一个大问题,因为在执行 docker-compose up 时它必须是 777 才能工作,但随后会由于全局可写而继续失败问题。