[英]Cannot connect to MySQL db using docker container
我在Typescript
中編寫了一個應用程序,它使用Typeorm
與MySQL
數據庫進行交互。 當我使用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
中啟動的,所以默認情況下,它們可以通過主機名(例如app
和db
)相互訪問。 要嘗試這一點,請將它們啟動, 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.