簡體   English   中英

無法使用 docker 容器連接到 MySQL 數據庫

[英]Cannot connect to MySQL db using docker container

我在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容器容器,我可以建立連接。

似乎只與容器連接有關的問題,也許應用程序的容器不知道 .network 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容器中看到的那樣,每個端口都正確暴露:

在此處輸入圖像描述

這里的問題是每個容器都使用自己的網絡,即使我在端口3306上暴露了mysql容器,我也無法從myapp容器訪問mysql ,因為myapp容器使用另一個網絡。

所以執行以下命令: docker network ls我能夠列出所有可用的網絡,然后我做了:

docker network inspect bridge

它返回了以下gateway :172.17.0.1

解決方案是將localhost替換為172.17.0.1 但是我不太喜歡下面的解決方案,所以我重建了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 上可用。

我不知道是否有更好的解決方案,到目前為止我是一個Docker ,所以也許這方面的專家可以提出一個更好的解決方案來共享容器網絡,例如mysql ,然后訪問該共享來自其他容器的網絡。

另一種解決方案是"host": "host.docker.internal"

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 to app ,然后嘗試ping db

https://stackoverflow.com/a/30173220/1148483

這意味着在您的應用程序中,您可以使用db作為數據庫主機配置。

我們不使用localhost ,而是將其替換為host.docker.internal 這將允許您連接到本地數據庫

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM