修复Docker中完全可写的MySQL错误

ef1yzkbh  于 2022-10-03  发布在  Docker
关注(0)|答案(8)|浏览(169)

我使用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/

此映像的我的Docker文件为:


# 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

目前,除了基本的MySQL图像之外,所有内容都被注解了。

问题是,当我启动容器时,MySQL将不会使用我的MySQL CNF文件,因为以下警告:
MySQLD:[警告]完全可写的配置文件‘/etc/mysql/conf.d/my.cnf’被忽略。

我正在使用Windows作为我的主机系统。问题是,Docker装载的目录具有完全权限,并且无法更改。

问题是,如何才能解决这个问题呢?正如您在我的Docker文件中看到的,我已经尝试了几种解决方案,但它们都不适用于我(但可能我做错了什么)。

目前,我认为最合理的解决方案是将MySQL conf文件不是直接挂载到/etc/mysql/conf.d/中,而是挂载到其他目录中,并在MySQL启动之前将这些文件复制到/etc/mysql/conf.d/目录中,并设置它们不具有777权限。我试过了,但在Dockerfile中,这些文件还不存在,所以无法复制。

有什么简单的解决方案可以解决这个问题吗?或者,也许可以将某些MySQL设置更改为不关心conf文件权限?

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

t3psigkw

t3psigkw1#

我刚刚遇到了这个问题,我的解决方案是在Windows中将my.cnf文件设置为只读。

pu82cl6c

pu82cl6c2#

对于使用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"]

docker-compose.yml(只显示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/source
    - /c/Users/marcin/dock-test/composers/l1.app/mysql/log/:/var/log/mysql/

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

start.sh


# !/bin/sh

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

/entrypoint.sh mysqld

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

要验证现在是否加载了自定义MySQL配置值,我运行:

mysql -u root -p

然后输入我的密码。

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

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

vvppvyoh

vvppvyoh3#

这对我很管用

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'
w9apscun

w9apscun4#

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

在docker编写文件中,您可以执行以下操作。

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

注意,我运行mySQLD,然后以选项--group_concat_max_len为例进行设置。如果需要更多选项,只需在带有选项名称的""中添加更多--即可。这是一个优雅的解决方案,不需要从默认的MySQL镜像创建新的镜像。

命令在docker合成文件中的作用是覆盖镜像中默认的cmd命令。图像的默认命令只是运行mysqld(您可以在他们的GitHub页面上查找它),所以我只是简单地运行它,但是给它一些参数来传递。请参阅该文件的最后一行以查看CMD命令。(参考:https://github.com/docker-library/mysql/blob/master/5.5/Dockerfile)

使用这种方法,你甚至不需要担心MySQL配置文件中的容量,这对我来说是一个大问题,因为在进行docker-compose时,它必须是777才能工作,但随后会因为世界可写问题而失败。

f87krz0w

f87krz0w5#

多亏了@marcin-nabiałek的灵感,我让这个解决方案工作起来,而不必编写一个定制的脚本来运行命令,因为我仍然会遇到权限问题。可以使用Dockerfile命令来完成脚本内容(请参阅下面的mariadb/Dockerfile内容)。

我在project-root目录中运行docker-compose -p my_project up --build -d

文件结构如下。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(请注意卷的相对路径):

(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

# etcmysqlconf.d being the VM path

COPY .conf* etcmysqlconf.d

# Make the conf files not writeable so mysql will read them

RUN chmod a-w etcmysqlconf.d*

这让我得到了我所需要的一切&我头上还有一些头发。如果这对其他人有帮助,请让我知道。

66bbxpm5

66bbxpm56#

其他答案对我不起作用,因为chownchmod告诉我文件夹的文件系统是只读的(即使用Nedudi's answer)。因此,我不得不删除该文件夹并重新创建:

FROM mariadb:10.8
RUN rm -rf /etc/mysql/conf.d
COPY --chown=mysql:mysql ./docker/misc/mariadb/mariadb.cnf /etc/mysql/mariadb.cnf
8wtpewkr

8wtpewkr7#

现在您正在使用卷主机装载,由于您的主机是Windows,因此会导致权限问题。

由于您想要为您的配置使用卷的主要原因是为了在容器之间共享,因此我建议您使用数据卷容器。

数据卷容器将包含您想要共享的卷,并且这些卷将是Linux装载的,因此权限问题应该会消失。

您的其他容器将使用数据容器卷作为配置卷。

有关创建和使用数据容器的信息可以在此处找到。

Https://docs.docker.com/engine/userguide/containers/dockervolumes/#creating-and-mounting-a-data-volume-container

一旦您设置了数据卷容器,您将在docker run上使用--volures-from标志来链接到容器并附加卷。

您可以对所有卷使用此方法,也可以只对少数卷使用此方法,无论您喜欢什么。

如果您不需要在其他容器之间共享数据,另一个选择是只使用常规卷,而不是主机装载的卷。这将在Linux中创建一个卷,但不会装载到Windows主机上。您只需列出具有一个目录名的卷即可。

Volumes
 - /var/lib/mysql
 - /etc/mysql
3zwjbxry

3zwjbxry8#

- /c/Users/marcin/dock-test/composers/l1.app/mysql/conf.d/:/etc/mysql/conf.d/:delegated

使用Delegated将主机路径设置为只读模式。

相关问题