【问题标题】:Connecting to mysql in docker fails在docker中连接mysql失败
【发布时间】:2019-04-25 00:39:32
【问题描述】:

我正在设置一个 Dockerfile,我可以在其中运行我的自动化测试,但在连接到 mysql 数据库时遇到了问题。

Dockerfile 依赖于预先构建的映像,如下所示:

# Stage 0, assign argument as multistage image alias
ARG PHP_IMAGE
FROM ${PHP_IMAGE} as image

# Stage 1, start tests
FROM php:7.2-fpm

RUN curl -sS https://getcomposer.org/installer | php \
  && chmod +x composer.phar && mv composer.phar /usr/local/bin/composer

RUN apt-get update && apt-get install -y gnupg
RUN curl -sL https://deb.nodesource.com/setup_8.x | bash - && \
    apt-get install -yq nodejs build-essential \
        git unzip \
        libfreetype6-dev \
        libjpeg62-turbo-dev \
        libmcrypt-dev \
        libpng-dev \
        subversion \
    && curl -sL https://deb.nodesource.com/setup_8.x | bash - \
    && pecl install mcrypt-1.0.1 \
    && docker-php-ext-enable mcrypt \
    && docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
    && docker-php-ext-install -j$(nproc) gd \
    && docker-php-ext-install -j$(nproc) mysqli

RUN apt-get install -y mysql-server
RUN /etc/init.d/mysql start
RUN mysqladmin -u root -p status

RUN yes | pecl install xdebug \
    && echo "zend_extension=$(find /usr/local/lib/php/extensions/ -name xdebug.so)" > /usr/local/etc/php/conf.d/xdebug.ini \
    && echo "xdebug.remote_enable=on" >> /usr/local/etc/php/conf.d/xdebug.ini \
    && echo "xdebug.remote_autostart=off" >> /usr/local/etc/php/conf.d/xdebug.ini

RUN npm install -g npm

COPY --from=image /var/www/html/ /var/www/html/

WORKDIR /var/www/html/
COPY scripts/develop.sh develop.sh
COPY scripts/docker-test.sh docker-test.sh

RUN ["/bin/bash", "-c", "bash develop.sh && bash docker-test.sh"]

我添加了RUN mysqladmin -u root -p status 来尝试调试为什么连接到mysql失败,我得到了

输入密码:mysqladmin:连接到'localhost'的服务器失败 error: 'Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2 "No such file or directory")' 检查 mysqld 是否正在运行并且套接字:'/var/run/mysqld/mysqld.sock' 存在!

为了运行这个我正在运行

docker build -t $TEST_DOCKER_NAME --build-arg PHP_IMAGE=$DOCKER_IMAGE_NAME_PHP -f Dockerfile.test .

TEST_DOCKER_NAMEDOCKER_IMAGE_NAME_PHP 存储在一个 env 文件中并从那里读取。 PHP 映像已成功构建,我正在使用它将文件从那里复制到这里,以便我可以运行 PHPUnit。

当我删除 RUN 行时,当我尝试运行创建数据库的脚本时,我的构建失败

mysqladmin: 连接到 'localhost' 的服务器失败 错误:'无法连接到'localhost'上的MySQL服务器(99“无法分配请求的地址”)' 检查 mysqld 是否在 localhost 上运行并且端口是 3306。 您可以通过执行 'telnet localhost 3306' 来检查这一点

我需要在我的 Dockerfile 中做什么才能使其正常工作?

【问题讨论】:

  • 如果status是密码正确的语法应该是mysqladmin -u root -pstatus
  • 我删除了密码,它显示了mysqladmin 命令的输出...
  • 未来:不要删除密码,只需将其更改为****PASSWORD

标签: mysql docker


【解决方案1】:

回答您的具体问题

这是人们在使用 docker 时常犯的错误。当您在 docker 中使用 RUN 指令时,您正在运行一个命令直到完成,捕获文件系统更改然后退出。

所以当你有线条时

RUN /etc/init.d/mysql start
RUN mysqladmin -u root -p status

第一个是启动mysql。但随后更改被捕获,退出容器,然后启动一个新容器以运行mysqladmin 命令。因此mysql进程不再运行。

为避免这种情况,您可以将它们组合成一行

RUN /etc/init.d/mysql start && mysqladmin -u root -p status

但是,每次您想使用 mysql 时都需要这样做。比如你的develop.sh

更广泛的答案

不建议在您的容器内运行多个进程,也不建议在您的容器内使用init.d 或其他系统启动框架。

您似乎将容器视为虚拟机,但由于容器不是虚拟机而遇到问题。

我建议您探索在单独的容器中运行 mysql,然后使用像 docker-compose 这样的工具来启动和停止您的容器。

【讨论】:

  • 是的,我错过了 docker 的重点(我是 docker 的菜鸟)。我以这种方式使用它而不是 docker compose,因为它在 Jenkins 管道中作为一个阶段运行。我有一个用于 php 的 dockerfile,然后是一个用于 nginx 的 dockerfile,现在我想做同样的事情来自动化项目上的运行测试。另外,我想自己做,而不是唠叨我的 devops,这样我就可以了解更多:D 我会看看如何解决这个问题。感谢您的建议!
  • 欢迎来到 docker 的精彩世界!我原以为您可以同时运行两个容器作为 jenkins 管道的一部分,这样您就可以一起运行 mysql 和 php。
  • 实际上,这就是让我有点困惑的部分。我在我的 Mac 上本地运行它,以避免等待 Jenkins 管道的每个部分完成(构建需要大约 8 分钟),我认为我的 PHP 图像(mysql、composer、node 等)中的所有东西都会当我执行FROM ${PHP_IMAGE} as image 时,我可以使用,但它们不是。再说一次,我确定我做错了什么XD
  • 图像中的所有内容都将可用。但是什么都不会运行。
  • 啊,我想念您使用的是分阶段构建。您只能访问最后阶段的资源。
猜你喜欢
  • 1970-01-01
  • 2017-06-25
  • 2019-03-05
  • 2016-02-24
  • 1970-01-01
  • 2022-08-05
  • 2020-05-11
  • 2015-01-05
  • 1970-01-01
相关资源
最近更新 更多