Laravel Docker容器无法连接本地MySQL

7

我在DockerFile中指定了本地运行的mysql,但连接时出现问题。

FROM php:7
RUN apt-get update -y && apt-get install -y openssl zip unzip git
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
RUN docker-php-ext-install pdo mbstring pdo_mysql
WORKDIR /home
COPY . /home
RUN composer install --ignore-platform-reqs

CMD php artisan serve --host=0.0.0.0 --port=8081
EXPOSE 8081

我在我的.env配置文件中加入了以下内容:

DB_HOST=localhost
DB_DATABASE=databasename
DB_USERNAME=root
DB_PASSWORD=testpassword

我对它失败的位置了解得很少。我是否需要为Docker容器安装MySQL呢?


那个 Docker 文件里面没有关于 MySQL 的任何引用吗? - mrhn
你能分享一下 docker-compose.yml 文件吗? - Efrat Levitan
嗨,我没有docker-compose.yml文件,因为只有一个服务需要运行,所以我只编写了Dockerfile。此外,在同一实例上,我有MySQL正在运行,但它不在Docker中,而是安装在机器本身上。 - Divyesh pal
4个回答

20

在Mac OSX和Docker for Windows中,一个更简单的解决方案是将主机地址从localhost替换为host.docker.internal

DB_HOST=host.docker.internal
DB_DATABASE=databasename
DB_USERNAME=root
DB_PASSWORD=testpassword

基本上,DNS名称host.docker.internal将解析为主机使用的内部IP地址。

NB:如果您已将地址更改为host.docker.internal但仍然收到“连接被拒绝”错误,则很可能是MySQL当前配置为仅侦听本地网络。

要解决这个问题,请在您的my.cnf配置文件中将bind_address的值更新为0.0.0.0


哇,这解决了我的问题。我不知道 host.docker.internal 实际上可以连接到本地主机。 - Mohammad.Kaab
伟大的人啊,这就是在Mac上运行Docker的解决方案。 - iWizard
虽然其他解决方案如“localhost、127.0.0.1或本地IP”会导致数据库迁移的冲突,但这个解决方案同样适用于Windows 11。非常好的解决方案。 - Melih

3
您正在尝试连接到MySQL的localhost,这是指本地主机(出人意料)。由于它是相对地址,在容器内被解析为容器自己的地址,并且没有MySQL在那里等待您... 因此,要解决此问题 - 只需将您的实际主机IP而不是localhost127.0.0.1提供给它。

步骤1 - 修复.env文件:

DB_HOST=<your_host_ip> #run `ifconfig` and look for your ip on `docker0` network
DB_DATABASE=databasename
DB_USERNAME=laravel_server #not root, since we are going to allow this user remote access.
DB_PASSWORD=testpassword

步骤2 - 创建专用用户:

打开您的MySQL:mysql -u root -p,输入您的root密码,并运行以下命令:

CREATE USER 'laravel_server'@'%' IDENTIFIED BY 'testpassword';
GRANT ALL PRIVILEGES ON databasename.* TO 'laravel_server'@'%'; 
FLUSH PRIVILEGES;

我们创建了用户并授予权限。

步骤3 - 开放MySQL远程访问:

我们必须使其在所有接口上侦听而不仅仅是localhost,因此我们运行:

sudo sed 's/.*bind-address.*/bind-address=0.0.0.0/' /etc/mysql/mysql.conf.d/mysqld.cnf

(您将被要求输入密码。此命令只会替换mysql配置文件中的一行)

步骤4 - 更新:

  1. 在项目目录中: php artisan config:cache
  2. service mysql restart

然后再次构建和运行新的docker容器,应该可以正常工作。


嗨,我尝试将我的公共IP放入环境中,但仍然无法连接。 - Divyesh pal
SQLSTATE[HY000] [2002] 没有这个文件或目录 (SQL: select * from mdk_services_types where service_name like %diabetic-care% limit 1) - Divyesh pal
我得到了“找不到该文件或目录”的错误。 - Divyesh pal
嘿,谢谢您的回复,请查看我的database.php文件:'mysql' => [ 'driver' => 'mysql', 'read' => [ 'host' => env('DB_HOST', 'localhost'), ], 'write' => [ 'host' => env('DB_HOST', 'localhost') ], 'port' => env('DB_PORT', '3306'), 'database' => env('DB_DATABASE', 'forge'), 'username' => env('DB_USERNAME', 'forge'), 'password' => env('DB_PASSWORD', ''), 'charset' => 'utf8', 'collation' => 'utf8_unicode_ci', ] - Divyesh pal
你需要允许远程连接到MySQL。为此,请将/etc/mysql/mysql.conf.d/mysqld.cnf文件中的bind_address127.0.0.1更改为0.0.0.0,并允许用户访问。 - Efrat Levitan
显示剩余4条评论

0

我看到有两个选项 -

  1. 使用您的Docker主机的私有IP,即MySQL服务器运行的位置。

  2. 在运行容器时使用主机网络模式,以防您想要使用本地主机。

    docker container --net=host ...


0
在我的情况下(Ubuntu 20.04桌面版),我已经运行了MariaDB并使用了3306端口。因此,当容器内的应用程序尝试启动容器内部的MySQL时,它会失败,因为它试图监听已经被占用的端口。我使用以下命令关闭了已经运行的MariaDB:
sudo systemctl stop mariadb.service

然后尝试启动Docker应用程序。它成功运行,因为端口3306现在是空闲的,并且由容器内的MySQL使用。但是,由于我打算同时使用它们,一个更加永久的解决方案是配置其中一个数据库系统,即Docker容器内部的或Docker容器外部的,以使用不同于默认3306的端口。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接