简体   繁体   English

系统能够连接到 mysql docker,但其他 docker 容器不能

[英]System able to connect to mysql docker, but other docker container cannot

This is my docker-compose file:这是我的 docker-compose 文件:

version: '3.9'
services:
  mysql:
    image: mysql:8.0
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    environment:
      MYSQL_DATABASE: 'admindb'
      MYSQL_USER: 'admin'
      MYSQL_PASSWORD: 'secretpassword'
      MYSQL_ROOT_PASSWORD: 'someverysecretpassword'
    ports:
      - '3306:3306'
      - '33060:33060'
    volumes:
      - ./db:/var/lib/mysql
    networks:
      - adminnet
  app:
    image: "node:latest"
    depends_on:
      - mysql
    user: "node"
    restart: unless-stopped
    working_dir: /home/app
    environment:
      NODE_ENV: production
    volumes:
      - ${PWD}/../:/home/app
    ports:
      - '8081:8081'
    command: "npm start"
    networks:
      - adminnet
volumes:
  db:
  data:

networks:
  adminnet:

And this is my app.js:这是我的 app.js:

const { Sequelize } = require('sequelize');

const sequelize = new Sequelize('admindb', 'admin', 'secretpassword', {
    host: 'mysql',
    port: 3306,
    dialect: 'mysql',
});

sequelize
  .authenticate()
  .then(() => {
    console.log('Connection has been established successfully.');
  })
  .catch(err => {
    console.error('Unable to connect to the database:', err);
  });

When I just run the MySQL container (so, if I remove the "app" instance from the docker-compose file) and replace host:'mysql' with host:'127.0.0.1' and run npm start from my host machine, it is able to successfully connect to the database, which runs from the container.当我只运行 MySQL 容器(因此,如果我从 docker-compose 文件中删除“app”实例)并将host:'mysql'替换为host:'127.0.0.1'并从我的主机运行npm start ,它能够成功连接到从容器运行的数据库。

But if I run app.js from a container, which should connect to the database inside the other container, it doesn't work.但是,如果我从一个容器运行 app.js,它应该连接到另一个容器内的数据库,它就不起作用。 I use host:'mysql' , but I keep getting the following error:我使用host:'mysql' ,但我不断收到以下错误:

containers-app-1    | Unable to connect to the database: ConnectionError [SequelizeConnectionError]: connect ETIMEDOUT
containers-app-1    |     at ConnectionManager.connect (/home/app/node_modules/sequelize/lib/dialects/mysql/connection-manager.js:102:17)
containers-app-1    |     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
containers-app-1    |     at async ConnectionManager._connect (/home/app/node_modules/sequelize/lib/dialects/abstract/connection-manager.js:220:24)
containers-app-1    |     at async /home/app/node_modules/sequelize/lib/dialects/abstract/connection-manager.js:174:32
containers-app-1    |     at async ConnectionManager.getConnection (/home/app/node_modules/sequelize/lib/dialects/abstract/connection-manager.js:197:7)
containers-app-1    |     at async /home/app/node_modules/sequelize/lib/sequelize.js:301:26
containers-app-1    |     at async Sequelize.authenticate (/home/app/node_modules/sequelize/lib/sequelize.js:453:5) {
containers-app-1    |   parent: Error: connect ETIMEDOUT
containers-app-1    |       at Connection._handleTimeoutError (/home/app/node_modules/mysql2/lib/connection.js:189:17)
containers-app-1    |       at listOnTimeout (node:internal/timers:564:17)
containers-app-1    |       at process.processTimers (node:internal/timers:507:7) {
containers-app-1    |     errorno: 'ETIMEDOUT',
containers-app-1    |     code: 'ETIMEDOUT',
containers-app-1    |     syscall: 'connect',
containers-app-1    |     fatal: true
containers-app-1    |   },
containers-app-1    |   original: Error: connect ETIMEDOUT
containers-app-1    |       at Connection._handleTimeoutError (/home/app/node_modules/mysql2/lib/connection.js:189:17)
containers-app-1    |       at listOnTimeout (node:internal/timers:564:17)
containers-app-1    |       at process.processTimers (node:internal/timers:507:7) {
containers-app-1    |     errorno: 'ETIMEDOUT',
containers-app-1    |     code: 'ETIMEDOUT',
containers-app-1    |     syscall: 'connect',
containers-app-1    |     fatal: true
containers-app-1    |   }
containers-app-1    | }

Something makes it impossible for the node-container to connect to the database inside the mysql-container.某些东西使节点容器无法连接到 mysql-container 内的数据库。 I tried to use ping from the node-container, but that package isn't available.我尝试使用节点容器中的 ping,但该包不可用。

I read a ton of webpages and I'm debugging for the past few hours, without luck.我阅读了大量网页,并且在过去的几个小时里一直在调试,但没有运气。 Anyone who might know the issue?有谁可能知道这个问题? I already tried all similar StackOverflow questions and solutions, without any luck.我已经尝试了所有类似的 StackOverflow 问题和解决方案,但没有任何运气。

I tested your stack on my machine and I got it working successfully, after a second run.我在我的机器上测试了你的堆栈,第二次运行后我成功地工作了。 I ran it twice because of your depends_on option (see my notes below).由于您的depends_on选项,我运行了两次(请参阅下面的注释)。

Here's my machine specs:这是我的机器规格:

Machine: MacBook Air (M1, 2020)机器: MacBook Air(M1,2020)
OS: macOS Monterey v12.4操作系统: macOS Monterey v12.4
Docker Version: 20.10.12 (installed with their .dmg) Docker 版本: 20.10.12(随 .dmg 一起安装)
Docker Compose Version: not used -- the latest version of docker includes it as a subcommand Docker Compose 版本:未使用——最新版本的 docker 将其作为子命令包含在内

And here's a git repo with my working copy of your app:这是一个带有我的应用程序工作副本的 git 存储库:
https://github.com/CodyEakins/question-73053680 https://github.com/CodyEakins/question-73053680

I think this problem has multiple causes:我认为这个问题有多种原因:

  1. Your docker-compose.yml file's depends_on option.您的 docker docker-compose.yml文件的depends_on选项。 If you read the documentation on depends_on , you'll see that your app service DOES NOT wait for mysql to be healthy before attempting a connection.如果您阅读有关depends_on文档,您会看到您的app服务在尝试连接之前不会等待mysql健康。 You have to use the healthcheck option if you want to make sure mysql is healthy before connecting.如果你想在连接之前确保mysql是健康的,你必须使用healthcheck选项
  2. There is a problem with your docker's internal host networking on your machine.您的机器上的 docker 内部主机网络存在问题。 This is hard to diagnose without knowing what OS you're using or what version of Docker you're running.如果不知道您正在使用什么操作系统或您正在运行什么版本的 Docker,这很难诊断。
  3. If you're using swarm mode with Docker, local bind mounts for volumes can be problematic/buggy.如果您在 Docker 中使用 swarm 模式,则卷的本地绑定挂载可能会出现问题/错误。 Not recommended.不建议。

PS - I also made some slight changes to your docker-compose.yml file inside my repo, namely regarding how you bind mount your app's package inside the container. PS - 我还对我的 repo 中docker-compose.yml文件进行了一些细微的更改,即关于如何将应用程序的包绑定到容器中。 Checkout my app service's volumes option ( link ) vs your own.查看我的app服务的volumes选项( 链接)与您自己的。

Try cloning my repo in a separate directory.尝试将我的 repo 克隆到一个单独的目录中。 Build/run it, and let me know the results.构建/运行它,让我知道结果。 You may have to use docker system prune to make sure there are no conflicts with my stack instance vs your stack instance.您可能必须使用docker system prune来确保我的堆栈实例与您的堆栈实例没有冲突。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM