无法使用Docker容器连接到MySQL数据库

时间:2020-07-05 11:31:57

标签: mysql node.js docker docker-compose docker-networking

我在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

我无法弄清楚这个问题,我也尝试将127.0.0.1更改为localhost,但还是同样的问题。这很奇怪,因为我也正在使用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

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

enter image description here

2 个答案:

答案 0 :(得分:0)

这里的问题是,即使我在端口mysql上暴露了3306容器,每个容器也使用各自的网络,但我无法从mysql容器访问myapp ,因为myapp容器使用另一个网络。

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

docker network inspect bridge

已返回以下gateway:172.17.0.1

解决方案是将localhost替换为172.17.0.1。但是我不太喜欢以下解决方案,因此我重建了myapp图像,该图像先前在network_mode内添加了docker-compose.yml,所以现在有了:

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

如文档所述:

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

我不知道是否有更好的解决方案,到目前为止,我是Docker菜鸟,所以也许对此有更多专家的人可以提出一个更好的解决方案来共享诸如{ {1}},然后从其他容器访问该共享网络。

另一种解决方法是mysql

答案 1 :(得分:0)

docker-compose

docker-compose不仅限于一项服务,您还可以拥有整个系统,在您的情况下,这意味着数据库服务器,您的应用程序以及其他所有东西。

您可以将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 attach/exec转到app,然后尝试ping db

请参见https://stackoverflow.com/a/30173220/1148483

这意味着在您的应用中,您可以将db用作数据库主机配置。