服务器容器无法连接到网络上的 MySQL 容器

Posted

技术标签:

【中文标题】服务器容器无法连接到网络上的 MySQL 容器【英文标题】:Server container can't connect to MySQL container on network 【发布时间】:2022-01-04 06:10:32 【问题描述】:

简介

大家好,

我正在构建一个我想使用 Docker 容器部署到 AWS 的网站。目前我正处于我的网站的开发阶段。

在我的网站中,我使用了一个 mysql 数据库容器、一个用于我的 GraphQL 服务器的容器和一个用于我的 React 前端的容器。

我面临的问题是我的服务器和数据库。 (注意,目前我没有使用 Docker Compose,我还在练习,但我确实打算使用它,所以要知道我目前没有 docker-compose.yml 文件给你看)

让你熟悉

这是我用来创建 MySQL 数据库容器的命令:

docker run --name larecipe-database --env-file ./env/mysql.env --network larecipe-net -p 3307:3306 -d mysql

我正在创建一个名为 larecipe-database 的 MySQL 容器。我正在为所有环境变量提供一个 env 文件,我将它与一个名为 larecipe-net 的网络连接起来,我正在公开端口 3307,它映射到端口 3306,显然,我正在使用 @987654327 @ 来自 docker hub 的图片。

这是我的数据库的 env 文件:

MYSQL_USER=raj
MYSQL_PASSWORD=password
MYSQL_DATABASE=larecipe

我的数据库就是这样,现在让我介绍一下我的服务器的 Dockerfile(注意,我使用的是 typescript,因此是 npm run watch):

FROM node

WORKDIR /app

COPY package.json .

RUN npm i

COPY . .

RUN npm run watch

EXPOSE 4000

CMD ["npm", "start"]

这是我的服务器的 .dockerignore 文件:

node_modules

这是我用来创建服务器镜像的命令,给它一个标签larecipe-server

docker build -t larecipe-server ./server

这是我用来创建服务器容器的命令:

docker run --name larecipe-server --env-file ./env/server.env --network larecipe-net -p 4000:4000 -d larecipe-server

这里我使用我创建的larecipe-server 映像,创建一个同名容器,为其提供一个 env 文件,将其连接到我用于数据库容器的同一网络,公开端口 4000,然后运行它处于分离模式。

这是服务器的 env 文件(与数据库相同):

MYSQL_USER=raj
MYSQL_PASSWORD=password
MYSQL_DATABASE=larecipe

问题

问题是我的服务器容器无法连接到我的mysql容器。

这是服务器用来连接的代码:

const  MYSQL_USER, MYSQL_PASSWORD, MYSQL_DATABASE  = process.env;

await createConnection(
    type: "mysql",
    host: "larecipe-database",
    port: 3307,
    username: MYSQL_USER,
    password: MYSQL_PASSWORD,
    database: MYSQL_DATABASE,
    logging: true,
    synchronize: true,
    entities: [Recipe, Ingredient, Step, Member],
  )
    .then(() => 
      console.log(chalk.greenBright.bold("server connected to database"));
    )
    .catch((e) => 
      console.error(e);
      console.log(chalk.redBright.bold("server not connected to database"));
    );

注意:

createConnection() 函数来自 typeorm,这是我用来与数据库交互的库

当我运行以下命令时:

docker logs larecipe-server

我得到以下输出:

Error: connect ECONNREFUSED 172.22.0.2:3307
    at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1161:16)
    --------------------
    at Protocol._enqueue (/app/node_modules/mysql/lib/protocol/Protocol.js:144:48)
    at Protocol.handshake (/app/node_modules/mysql/lib/protocol/Protocol.js:51:23)
    at PoolConnection.connect (/app/node_modules/mysql/lib/Connection.js:116:18)
    at Pool.getConnection (/app/node_modules/mysql/lib/Pool.js:48:16)
    at /app/node_modules/typeorm/driver/mysql/MysqlDriver.js:863:18
    at new Promise (<anonymous>)
    at MysqlDriver.createPool (/app/node_modules/typeorm/driver/mysql/MysqlDriver.js:860:16)
    at MysqlDriver.<anonymous> (/app/node_modules/typeorm/driver/mysql/MysqlDriver.js:288:51)
    at step (/app/node_modules/tslib/tslib.js:143:27)
    at Object.next (/app/node_modules/tslib/tslib.js:124:57) 
  errno: -111,
  code: 'ECONNREFUSED',
  syscall: 'connect',
  address: '172.22.0.2',
  port: 3307,
  fatal: true


server not connected to database

我的理解是我应该能够将larecipe-database 作为我的主机,因为两个容器都在同一个网络上。我正在使用端口3307,因为这是我暴露的端口。

我的成功尝试:

我做的第一件事是转到 MySQL 工作台,并尝试从那里连接,但这也不起作用。

接下来我使用以下命令检查网络本身:

docker network inspect larecipe-net

这是我收到的输出:

[
    
        "Name": "larecipe-net",
        "Id": "2b20e4bb771b32727adc747259bee4c0c51eda05e396060200faef16336ce983",
        "Created": "2021-11-26T04:30:57.92577585Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": 
            "Driver": "default",
            "Options": ,
            "Config": [
                
                    "Subnet": "172.22.0.0/16",
                    "Gateway": "172.22.0.1"
                
            ]
        ,
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": 
            "Network": ""
        ,
        "ConfigOnly": false,
        "Containers": 
            "ad3ae92c0acbd90ce2c7da786ef02456626e71f3fd087694528f29239bfe932b": 
                "Name": "larecipe-server",
                "EndpointID": "e4a4fff37d3efb34dcc77b6bcfd9279f1357f48a7b0ccb0461b6041132f2d5bf",
                "MacAddress": "02:42:ac:16:00:03",
                "IPv4Address": "172.22.0.3/16",
                "IPv6Address": ""
            ,
            "d0b02575ced53453f9b9309a355b92d3ac95c31977fdf0e2ba6e498b1e79884d": 
                "Name": "larecipe-database",
                "EndpointID": "f8cb24ab9e3d7df154eace0cf360d559d58f7e094d0d96c6df5087362250229e",
                "MacAddress": "02:42:ac:16:00:02",
                "IPv4Address": "172.22.0.2/16",
                "IPv6Address": ""
            
        ,
        "Options": ,
        "Labels": 
    
]

在数组内对象的Containers 属性下,我意识到两个容器有不同的IPv4Addresss。我不知道这意味着什么,因为我不是网络专家,但我尝试了两个地址,端口为 3307,但我仍然无法连接。

提前感谢您提供任何反馈和解决方案。 如果您需要任何额外信息,请告诉我。

【问题讨论】:

您可以尝试在 Workbench 中禁用 SSL 并连接吗?我的方法是先让 Workbench 连接正常工作。 请原谅我的提问,但是如何在工作台中禁用 SSL?我似乎没有选择这样做。我对 SSL 的唯一选项是“要求”、“要求并验证 CA”和“要求并验证身份”。 连接方法应该是Standard(TCP/IP)而不是Standard(TCP/IP) over SSL。您是否也尝试过使用 localhost,即没有在 Docker 中定义网络? 我的连接方式确实是使用Standard(TCP/IP),但还是无法禁用SSL。另外,使用 Docker 的全部意义在于,我不必使用 localhost 并且我的服务不必依赖于我的本地机器,或者这就是我的想法。我绝对可以使用 localhost,但我想尝试使用 Docker 网络。 但是有一个选项可以做Standard(TCP/IP) over SSH。我会试试的。非常感谢您迄今为止的帮助! 【参考方案1】:

难以置信!我解决了!我只需要将我的主机更改为host.docker.internal!现在我将尝试将这些容器放在网络上。

【讨论】:

以上是关于服务器容器无法连接到网络上的 MySQL 容器的主要内容,如果未能解决你的问题,请参考以下文章

Mariadb docker容器无法使用Python连接到主机上的MySQL服务器(111连接被拒绝)

无法从Spring Boot Docker容器连接到本地MySQL数据库服务器

通过 Beanstalk 部署的 Docker 容器无法连接到 RDS 上的数据库

无法从 docker 容器连接到 SQL Server

docker 容器中的 Keycloak + 主机上的 MySQL 提供 [org.keycloak.services] (ServerService 线程池 -- 62) 无法连接到数据库

Spring boot JDBC无法连接到docker容器中的mysql