提问者:小点点

无法使用docker容器连接到MySQL db


我用Typescript编写了一个应用程序,它使用TypeORMMySQL数据库交互。 当我使用npm run dev(即package.json脚本)运行应用程序时,连接在以下凭据下运行良好:

"type": "mysql",
"host": "127.0.0.1",
"port": 3306,
"username": "root",
"password": "root",
"database": "mydb",

但是当我启动docker容器时,我得到:

> Error: connect ECONNREFUSED 127.0.0.1:3306
> errno: -111,
> code: 'ECONNREFUSED',
> syscall: 'connect',
> address: '127.0.0.1',
> port: 3306,
> fatal: true

我无法解决这个问题,我也尝试用localhost更改127.0.0.1,但是同样的问题。 这很奇怪,因为我正在使用DBEaver连接我的LAMP,它也是一个Docker容器容器,我可以建立连接。

似乎只与容器连接有关的问题,可能应用程序的容器不知道网络127.0.0.1

这是我的图像文件:

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"]

这是我的docker-compose.yml:

version: '3'
services:
  app:
    container_name: myapp
    restart: always
    build: .
    ports:
      - '4000:4000'

对于编译容器,我做了:docker-compose up--build

怎么啦? 从我的容器中可以看到,每个端口都正确暴露:


共2个答案

匿名用户

这里的问题是,每个容器都使用自己的网络,即使我在端口3306上公开了mySQL容器,我也无法从myapp容器访问mySQL,因为myapp容器使用另一个网络。

因此,执行以下命令:docker network ls我能够列出所有可用的网络,然后我就这样做了:

docker network inspect bridge

返回以下gateway:172.17.0.1

解决方案是用172.17.0.1替换localhost。 但是我不太喜欢下面的解决方案,所以我重新构建了myapp图像,在docker-compose.yml中添加了以前的network_mode,所以现在我有了:

version: '3'
services:
  app:
    container_name: myapp
    restart: always
    build: .
    ports:
      - '4000:4000'
    network_mode: 'host'

如文件所述:

如果对容器使用主机网络模式,则该容器的网络堆栈与Docker主机不隔离(容器共享主机的网络命名空间),并且该容器不会分配自己的IP地址。 例如,如果您运行绑定到端口80的容器,并且使用主机网络,则该容器的应用程序在主机IP地址的端口80上可用。

我不知道是否有更好的解决方案,到目前为止,我是一个dockernoob,所以也许在这方面有更多的专家可以提出一个更好的解决方案来共享容器网络,例如mysql,然后从其他容器访问该共享网络。

匿名用户

docker-compose并不局限于一个服务,您可以拥有整个系统,在您的示例中,这意味着DB服务器,您的应用程序和所有其他东西。

您可以将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'

因为容器是在同一个docker-compose中出现的,默认情况下,它们可以通过主机名(例如appdb)相互访问。 要进行尝试,请打开它们,docker附加/execapp,并尝试ping db

见https://stackoverflow.com/A/30173220/1148483

这意味着在应用程序中,可以使用DB作为DB主机配置。