在Docker容器中创建.my.cnf文件时出现错误

67次阅读
没有评论

问题描述

在尝试为MySQL Docker容器创建一个.my.cnf文件,以便预先填充MySQL客户端的用户名和密码。为了实现这一目标,他创建了以下Dockerfile:

FROM mysql:5.7
RUN touch ~/.my.cnf && echo -e "[client]\nuser=root\npassword=$(echo $MYSQL_ROOT_PASSWORD)" >> ~/.my.cnf

但是,当启动容器时,他总是遇到以下错误:

mysql5.7-database    | 2021-04-01 18:38:51+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.33-1debian10 started.
mysql5.7-database    | 2021-04-01 18:38:51+00:00 [ERROR] [Entrypoint]: mysqld failed while attempting to check config
mysql5.7-database    |  command was: mysqld --verbose --help --log-bin-index=/tmp/tmp.5imGsNRXXC
mysql5.7-database    |  mysqld: [ERROR] Found option without preceding group in config file /root/.my.cnf at line 1!
mysql5.7-database    | mysqld: [ERROR] Fatal error in defaults handling. Program aborted!

用户已经成功设置了环境变量$MYSQL_ROOT_PASSWORD并且可以使用该密码登录。执行echo -e "[client]\nuser=root\npassword=$(echo $MYSQL_ROOT_PASSWORD)"命令的结果如下:

[client]
user=root
password=<my-generated-password>

当用户在正在运行的Docker容器中手动创建.my.cnf文件时,一切正常。请问有什么建议吗?

解决方案

请注意以下操作注意版本差异及修改前做好备份。

方案1

问题出现在Dockerfile中的echo命令上。默认的Dockerfile shell是sh,我不认为echo命令有-e选项来处理反斜杠。换行符和其他特殊符号默认情况下会起作用。在你的命令中,生成的.my.cnf文件将包含一个字面上的-e。
你可以删除-e选项,或者在Dockerfile中使用原始命令的不同shell,例如:

RUN /bin/bash -c '<your-command>'

在上面的示例中,我们使用/bin/bash -c来运行你的命令。这将使用不同的shell来处理命令,可能会解决你遇到的问题。

方案2

如果你不想更改Dockerfile中的命令,你可以尝试在命令中使用单引号而不是双引号,如下所示:

RUN touch ~/.my.cnf && echo -e '[client]\nuser=root\npassword=$(echo $MYSQL_ROOT_PASSWORD)' >> ~/.my.cnf

这样,echo命令中的变量将不会被解析,而是作为字符串直接写入.my.cnf文件中。这可能会解决你遇到的问题。

方案3

如果以上解决方案都无法解决问题,你可以尝试在容器启动后手动创建.my.cnf文件。你可以使用一个启动脚本,在容器启动后执行所需的命令。以下是一个示例的bash脚本,可以在容器启动后创建.my.cnf文件:

#!/bin/bash
# 等待MySQL服务启动
while ! mysqladmin ping -h localhost --silent; do
  sleep 1
done
# 创建.my.cnf文件
echo -e "[client]\nuser=root\npassword=$MYSQL_ROOT_PASSWORD" > ~/.my.cnf

在这个示例中,我们使用一个循环来等待MySQL服务启动。一旦MySQL服务可用,我们使用echo命令创建.my.cnf文件,并将用户名和密码写入文件中。
请注意,这种方法需要在容器启动后手动执行脚本。你可以将脚本放在容器中,并在启动容器时运行它,或者使用一些工具来管理容器的启动顺序。
以上是几种可能的解决方案,希望其中之一能够解决你的问题。

正文完