[英]Cannot connect to MySQL db using docker container
I wrote an application in Typescript
which use Typeorm
to interact with a MySQL
database.我在
Typescript
中编写了一个应用程序,它使用Typeorm
与MySQL
数据库进行交互。 When I run the app using npm run dev
which is a package.json
script, the connection is working fine with these credentials:当我使用
npm run dev
运行应用程序时,这是一个package.json
脚本,使用这些凭据连接工作正常:
"type": "mysql",
"host": "127.0.0.1",
"port": 3306,
"username": "root",
"password": "root",
"database": "mydb",
but when I launch my Docker
container I get:但是当我启动我的
Docker
容器时,我得到:
> Error: connect ECONNREFUSED 127.0.0.1:3306
> errno: -111,
> code: 'ECONNREFUSED',
> syscall: 'connect',
> address: '127.0.0.1',
> port: 3306,
> fatal: true
I cannot figure out of this problem, I also tried to change 127.0.0.1
with localhost
but same problem.我无法弄清楚这个问题,我也尝试用
localhost
更改127.0.0.1
但同样的问题。 That's weird 'cause I'm using Dbeaver
to connect with my LAMP
which is a Docker
container container too and I can establish the connection.这很奇怪,因为我正在使用
Dbeaver
连接我的LAMP
,它也是一个Docker
容器容器,我可以建立连接。
Seems a problem related only with the containers connection, maybe the container of the app doesn't know the.network 127.0.0.1
?似乎只与容器连接有关的问题,也许应用程序的容器不知道 .network
127.0.0.1
?
This is my image file:这是我的图像文件:
FROM node:stretch-slim
WORKDIR /myapp
COPY package.json ./
COPY ./dist ./dist
RUN npm install
EXPOSE 4000
ENV NODE_ENV development
ENV PORT 4000
ENV URL http://localhost:4000
ENV JWT_SECRET secret
CMD ["npm", "run", "start", "dev"]
and this is my docker-compose.yml
:这是我的
docker-compose.yml
:
version: '3'
services:
app:
container_name: myapp
restart: always
build: .
ports:
- '4000:4000'
for compile my containers I did: docker-compose up --build
为了编译我的容器,我做了:
docker-compose up --build
What is wrong?怎么了? As you can see from my
lamp
container each port is correctly exposed:正如您从我的
lamp
容器中看到的那样,每个端口都正确暴露:
The problem here is that each container use their own network, even though I exposed the mysql
container on port 3306
I cannot access to mysql
from the myapp
container, because myapp
container use another network.这里的问题是每个容器都使用自己的网络,即使我在端口
3306
上暴露了mysql
容器,我也无法从myapp
容器访问mysql
,因为myapp
容器使用另一个网络。
So executing the following command: docker network ls
I was able to list all the networks available, and then I did:所以执行以下命令:
docker network ls
我能够列出所有可用的网络,然后我做了:
docker network inspect bridge
which has returned the following gateway
: 172.17.0.1它返回了以下
gateway
:172.17.0.1
The solution would be to replace localhost
with 172.17.0.1
.解决方案是将
localhost
替换为172.17.0.1
。 But I don't like the following solution too much, so I rebuilded the myapp
image adding previously network_mode
inside the docker-compose.yml
, so now I have:但是我不太喜欢下面的解决方案,所以我重建了
myapp
图像,在docker-compose.yml
中添加了先前的network_mode
,所以现在我有了:
version: '3'
services:
app:
container_name: myapp
restart: always
build: .
ports:
- '4000:4000'
network_mode: 'host'
as documentation says:正如文档所说:
If you use the host network mode for a container, that container's network stack is not isolated from the Docker host (the container shares the host's networking namespace), and the container does not get its own IP-address allocated.
如果您为容器使用主机网络模式,则该容器的网络堆栈不会与 Docker 主机隔离(容器共享主机的网络命名空间),并且容器不会获得自己的 IP 地址分配。 For instance, if you run a container which binds to port 80 and you use host networking, the container's application is available on port 80 on the host's IP address.
例如,如果您运行一个绑定到端口 80 的容器并使用主机网络,则该容器的应用程序在主机的 IP 地址上的端口 80 上可用。
I don't know if there is a better solution out there, I'm a Docker
noob so far, so maybe someone more expert on this could propose a better solution to share a container network such as mysql
, and then access to that shared network from others containers.我不知道是否有更好的解决方案,到目前为止我是一个
Docker
,所以也许这方面的专家可以提出一个更好的解决方案来共享容器网络,例如mysql
,然后访问该共享来自其他容器的网络。
Another solution would be "host": "host.docker.internal"
另一种解决方案是
"host": "host.docker.internal"
docker-compose
docker-compose
isn't limited to just one service, you can have the whole system, which, in your case, means the DB server, your app, and all the other things. docker-compose
不仅限于一项服务,您可以拥有整个系统,在您的情况下,这意味着数据库服务器、您的应用程序和所有其他东西。
You can change your docker-compose.yml
file to something like below (MySQL bit copied from https://hub.docker.com/_/mysql )您可以将
docker-compose.yml
文件更改为如下所示(从https://hub.docker.com/_/mysql复制的 MySQL 位)
version: '3'
services:
db:
image: mysql
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
MYSQL_ROOT_PASSWORD: example
app:
container_name: myapp
restart: always
build: .
ports:
- '4000:4000'
Because your containers are brought up in the same docker-compose
, by default they have access to each other by hostname eg app
, and db
.因为您的容器是在同一个
docker-compose
中启动的,所以默认情况下,它们可以通过主机名(例如app
和db
)相互访问。 To try this out, bring them up, docker attach/exec
to app
, and try a ping db
.要尝试这一点,请将它们启动,
docker attach/exec
to app
,然后尝试ping db
。
See https://stackoverflow.com/a/30173220/1148483见https://stackoverflow.com/a/30173220/1148483
This means that in your app, you can use db
as the DB host config.这意味着在您的应用程序中,您可以使用
db
作为数据库主机配置。
Instead of using localhost
, let's replace it with host.docker.internal
.我们不使用
localhost
,而是将其替换为host.docker.internal
。 This will allow you to connect with your local db这将允许您连接到本地数据库
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.