【问题标题】:Docker - MySQL commands within Dockerfile using RUN (ERROR 2002)Docker - 使用 RUN 的 Dockerfile 中的 MySQL 命令(错误 2002)
【发布时间】:2016-05-30 12:02:10
【问题描述】:

我正在使用 Docker 创建一个以 mysql 作为基础镜像的 dockerfile:

FROM mysql
#set root pass
ENV MYSQL_ROOT_PASSWORD password
#update linux
RUN apt-get update
#create database
RUN mysql -u root -ppassword -e "CREATE DATABASE dbname"
#install vim
RUN apt-get install vim -y

dockerfile 在我尝试创建数据库的步骤中失败,它没有完成构建并且我收到此错误:

错误 2002 (HY000):无法通过套接字 '/var/run/mysqld/mysqld.sock' 连接到本地 MySQL 服务器

当我删除#create database run 命令时,dockerfile 将构建并且我能够从该映像运行容器。我知道这不是mysql服务器的问题,因为我可以进入容器并手动运行mysql命令成功并且服务状态正在运行。

在文件中使用环境变量,即 MYSQL_ROOT_PASSWORD 也可以让我成功创建数据库,但这仅适用于单个数据库,我需要能够使用 mysql 命令进行查询,例如创建其他数据库 /分配用户等。

这可能是因为我需要指定 docker 容器的主机和端口,但这仍然不允许我连接

RUN mysql -u root -ppassword -h 127.0.0.1 -P 3308 -e "CREATE DATABASE dbname"

奇怪的是,这样做也经常使容器崩溃并使其处于每次我尝试再次重新启动它时它会在启动时再次崩溃的状态。

【问题讨论】:

    标签: mysql linux docker virtual-machine dockerfile


    【解决方案1】:

    我认为问题可能在于服务尚未在用于构建 Dockerfile 的容器中启动。

    【讨论】:

    • 我尝试了这个解决方案,方法是复制 MySQL Dockerfile 的内容并将我的查询添加到 RUN 命令的末尾,这样可以成功构建,但是我使用此图像创建的任何容器在启动时也会崩溃。
    • 您构建的容器默认不会运行所有服务。所以一旦你构建了容器,你应该再次启动 mysqld(在那个容器中)。
    • mysqld 已经在运行,因为它被设置为在启动时运行
    【解决方案2】:

    在您的 Dockerfile 中使用以下给出的命令:

    RUN service mysql restart && echo 'CREATE DATABASE db_name;' | mysql -uroot -
    pYOUR_ROOT_PASSWORD
    

    【讨论】:

      【解决方案3】:

      遇到了同样的问题:当启动容器并运行一组RUN 指令或/docker-entrypoint-initdb.d/ 中的.sh.sql 脚本时,无法建立与数据库服务器的连接。

      我在 mysql-image 上通过 comment of @wpalmer 找到了解决方案:

      入口点运行的初始化脚本,在内部使用变量“${mysql[@]}”来调用mysql(例如,在加载放在docker-entrypoint-initdb.d目录中的.sql文件时。任何由入口点处理的 .sh 文件通过“采购”它们包含在内,这意味着该变量可供任何正在运行的 .sh 文件使用。

      那么这对您意味着什么,而不是像中那样提供带有用户、密码等的普通 mysql 命令

      RUN mysql -u root -ppassword -e "CREATE DATABASE dbname"
      

      改用占位符:

      RUN "${mysql[@]}" -e "CREATE DATABASE dbname"
      

      【讨论】:

        【解决方案4】:

        您可以尝试构建其他映像并从那里运行创建数据库。 docker-compose.yml 示例

        web:
          build: web
          links:
          - "db:db.local"
          entrypoint: entrypoint.sh
        
        db:
          build: db
          environment:
             MYSQL_ROOT_PASSWORD: password
          command: mysqld
        

        对于 entrypoint.sh,你可以这样写:

        #!/bin/sh
        
        #this is a hack to wait until the DB image is up and the port is open
        until mysqladmin -u root -ppassword -e -h db.local ping; do
           echo "$(date) - waiting for mysql"
           sleep 3
        done
        
        if ! mysql -u root -ppassword -e -h db -e 'use dbname'; then
           mysql -u root -ppassword -e "CREATE DATABASE dbname"
        fi
        
        exec "$@"
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-04-13
          • 2020-12-12
          • 1970-01-01
          • 2019-03-27
          • 1970-01-01
          • 2018-02-23
          • 2015-05-23
          • 2019-10-19
          相关资源
          最近更新 更多