服务器容器无法连接到网络上的 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
属性下,我意识到两个容器有不同的IPv4Address
s。我不知道这意味着什么,因为我不是网络专家,但我尝试了两个地址,端口为 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 容器中的 Keycloak + 主机上的 MySQL 提供 [org.keycloak.services] (ServerService 线程池 -- 62) 无法连接到数据库