将带有Yii的docker容器连接到带有MySQL服务器的非链接docker容器

将带有Yii的docker容器连接到带有MySQL服务器的非链接docker容器,docker,yii,Docker,Yii,我有一个对接的Yii项目和nginx。我有一个单独的带有mysql服务器的docker容器,我将mysql转储导入其中 项目失败,出现错误: 2018-08-15 12:34:52 [-][-][-][error][yii\db\Exception] PDOException: SQLSTATE[HY000] [2002] Connection refused in /app/vendor/yiisoft/yii2/db/Connection.php:687 Stack trace: #0 /a

我有一个对接的Yii项目和nginx。我有一个单独的带有mysql服务器的docker容器,我将mysql转储导入其中

项目失败,出现错误:

2018-08-15 12:34:52 [-][-][-][error][yii\db\Exception] PDOException: SQLSTATE[HY000] [2002] Connection refused in /app/vendor/yiisoft/yii2/db/Connection.php:687
Stack trace:
#0 /app/vendor/yiisoft/yii2/db/Connection.php(687): PDO->__construct('mysql:host=127....', 'user', 'pass', NULL)
.............
我怀疑该项目的docker服务应该链接到
docker compose.yml
。大概是这样的:

version: '2'
services:

    app:
        image: app
        links:
            - db

    db:
        image: mysql:5.7
这是否可以在不链接docker服务的情况下连接到mysql服务器? 如果是,怎么做

更新1

我当前的docker-compose.yml:

version: '2'
services:

    yiiapp_nginx:
        image: nginx

        hostname: 'dev.yiiapp.com'

        depends_on:
          - yiiapp_app

        ports:
            - "80:80"

        volumes_from:
          - yiiapp_app

        volumes:
          - ./docker/nginx/conf:/etc/nginx/
          - ./docker/nginx/logs:/var/log/nginx

        container_name: "yiiapp_nginx"

    yiiapp_app:
        build:
            ./

        container_name: yiiapp_app

        hostname: 'dev.yiiapp.com'

        environment:

            MYSQL_DATABASE: yiiapp
            MYSQL_USER: yiiapp
            MYSQL_PASSWORD: yiiapp
            MYSQL_ROOT_PASSWORD: yiiapp


        volumes:
            - ~/.ssh/id_rsa:/root/.ssh/id_rsa:ro
            - ./:/app
            - ./docker/container-files/usr/local/etc/php-fpm.d/www.conf:/usr/local/etc/php-fpm.d/www.conf

        expose:
            - "9000"
version: '3'

services:
  yiiapp_nginx:
    image: nginx
    hostname: 'dev.yiiapp.com'
    depends_on:
      - yiiapp_app
    ports:
      - "80:80"
    volumes_from:
      - yiiapp_app
    volumes:
      - ./docker/nginx/conf:/etc/nginx/
      - ./docker/nginx/logs:/var/log/nginx
    container_name: "yiiapp_nginx"
    networks:
      - frontend

  yiiapp_app:
    build: .
    container_name: yiiapp_app
    hostname: 'dev.yiiapp.com'
    environment:
        - MYSQL_DATABASE=yiiapp
        - MYSQL_USER=yiiapp
        - MYSQL_PASSWORD=yiiapp
        - MYSQL_ROOT_PASSWORD=yiiapp
    volumes:
        - ~/.ssh/id_rsa:/root/.ssh/id_rsa:ro
        - ./:/app
        - ./docker/container-files/usr/local/etc/php-fpm.d/www.conf:/usr/local/etc/php-fpm.d/www.conf
    expose:
        - "9000"
    network:
        - backend_network
        - frontend

networks:
  backend_network:
    external:
      name: backend

  frontend:
    name: yiiapp_frontend
    driver: bridge
更新2

这就是我在我的案例中解决问题的方法。 对于每个单独的
docker compose.yml
docker实际上创建了一个单独的网络

在幕后,Docker引擎创建了必要的Linux 桥接器、内部接口、iptables规则和主机路由 这种连接是可能的

因此,从我的本地机器上,我可以自由访问这两个容器,但它们不能相互访问。在不修改现有的
docker compose.yml
的情况下,我运行了:

 docker network create yiiapp_network
 docker network connect yiiapp_network mysql_container
 docker network connect yiiapp_network yiiapp_app
 docker network connect yiiapp_network yiiapp_nginx
 docker network inspect yiiapp_network
它创建了一个新网络并向其中添加了所有容器

另外,我将db主机名更改为我的db容器名称:

$db_host = 'mysql_container';

它成功了。

您是否正在尝试从应用程序连接到
127.0.0.1
?如果是这样,您必须将其更改为
docker compose
中运行数据库的服务的名称,即db。 看到您的错误消息,您应该有类似的内容:

('mysql:host=db', 'user', 'pass', NULL)
并确保这两个容器位于同一网络中,以便它们可以相互联系。 如果您不指定特定的网络,默认情况下,它们将位于同一个网络中,并且您不需要将它们链接到另一个网络

更新docker compose后编辑

由于数据库容器和应用程序容器不在同一docker compose中运行,并且您没有强制它们中的任何一个加入特定的网络,因此它们不在同一网络中,并且无法相互联系

如果不想,不需要在主机网络上公开数据库端口。您只需创建一个专用于您的应用程序的网络,我们称之为
后端

docker network create backend
默认情况下,它将使用网桥驱动程序,并且只有来自同一主机的容器才能连接到网络

无需停止数据库容器即可将其连接到
后端网络,只需运行:

docker network connect backend <db_container_name>
使用docker compose up--build
重新构建您的撰写堆栈,它应该可以正常工作


您肯定希望mysql数据库容器始终保持在
后端
网络中,因此以相同的方式修改其
docker运行脚本
或其
docker compose
。请参阅docker networking文档

您是否正在尝试从应用程序连接到
127.0.0.1
?如果是这样,您必须将其更改为
docker compose
中运行数据库的服务的名称,即db。 看到您的错误消息,您应该有类似的内容:

('mysql:host=db', 'user', 'pass', NULL)
并确保这两个容器位于同一网络中,以便它们可以相互联系。 如果您不指定特定的网络,默认情况下,它们将位于同一个网络中,并且您不需要将它们链接到另一个网络

更新docker compose后编辑

由于数据库容器和应用程序容器不在同一docker compose中运行,并且您没有强制它们中的任何一个加入特定的网络,因此它们不在同一网络中,并且无法相互联系

如果不想,不需要在主机网络上公开数据库端口。您只需创建一个专用于您的应用程序的网络,我们称之为
后端

docker network create backend
默认情况下,它将使用网桥驱动程序,并且只有来自同一主机的容器才能连接到网络

无需停止数据库容器即可将其连接到
后端网络,只需运行:

docker network connect backend <db_container_name>
使用docker compose up--build
重新构建您的撰写堆栈,它应该可以正常工作


您肯定希望mysql数据库容器始终保持在
后端
网络中,因此以相同的方式修改其
docker运行脚本
或其
docker compose
。请参阅docker networking文档

如果在同一docker compose文件中有
db
服务,则无需从外部提供任何链接。您可以从
yii
app
容器中通过名称
db
来调用它。确保在
yii
app
服务/容器的连接字符串中使用
db
作为mysql主机名

('mysql:host=db','user','pass',NULL)

重新创建容器-

$docker编写构建;docker compose up-d

如果您的mysql存在于主机上,您可以将主机IP放入连接字符串,或者在docker compose中使用
网络模式(首选),将以下内容添加到docker compose的
应用程序/yii
服务并重新构建容器-

网络模式:“主机”

使用网络模式:“主机”
后,需要将连接字符串更改为(主机=127.0.0.1,端口=3306)-

('mysql:host=127.0.0.1….','user','pass',NULL)


Ref-

如果在同一docker compose文件中有
db
服务,则无需从外部提供任何链接。您可以从
yii
app
容器中通过名称
db
来调用它。确保在
yii
app
服务/容器的连接字符串中使用
db
作为mysql主机名

('mysql:host=db','user','pass',NULL)

重新创建容器-

$docker编写构建;docker compose up-d

万一你