【问题标题】:Docker(docker-compose) node + MySQL: ECONNREFUSEDDocker(docker-compose)节点+ MySQL:ECONNREFUSED
【发布时间】:2020-05-16 17:05:00
【问题描述】:

我有一个 docker-compose.yml 文件,它正在运行三个容器。我的问题是,当我启动容器时,似乎我的 node(api) 容器在我的 MySQL 容器之前启动,即使我在 docker-compose.yml 上声明了depends_on,也会出现以下错误:

error connecting: Error: connect ECONNREFUSED xxx.xx.x.x:3306
at TCPConnectWrap.afterConnect [as oncomplete]

收到此错误后,我可以在控制台中看到 MySQL 容器刚刚启动。我的数据库没问题,我可以毫无问题地访问它。如果我对我的 nodejs 代码进行一些更改,那么这将使我的节点服务器刷新,当服务器再次启动时,我没有任何连接问题,因为 MySQL 容器已经启动。

我什至尝试使用wait-for-it.sh(https://github.com/vishnubob/wait-for-it/blob/master/wait-for-it.sh)的解决方案,但结果是一样的,我的节点后端尝试建立mysql连接,但是mysql容器没有准备好。

这是我的 docker-compose.yml

version: "3"
services:
    mysql:
        image: my_mysql
        build: ./db
        restart: always
        container_name: my_mysql
        volumes:
            - /var/lib/mysql
            - ./db:/db
        ports:
            - "3307:3306"
        environment:
            - MYSQL_ROOT_PASSWORD=x 
            - MYSQL_USER=x
            - MYSQL_PASSWORD=x
            - MYSQL_DATABASE=x
        networks: 
            - my_network
        command: --default-authentication-plugin=mysql_native_password
    api:
        container_name: my_api
        build: ./api
        restart: always
        ports:
            - "9000:9000"
        environment:
            DB_HOSTNAME: mysql    
        working_dir: /api
        volumes:
            - ./api:/api
        depends_on: 
            - mysql
        networks:
            - my_network
    client:
        container_name: my_client
        image: mhart/alpine-node:12
        build: ./client
        restart: always
        ports:
            - "3000:3000"
        working_dir: /client
        volumes:
            - ./client:/client
        entrypoint: ["npm", "start"]
        depends_on: 
            - api
        networks: 
            - my_network
networks:
    my_network:
        driver: bridge

我的 nodejs 后端的 Dockerfile:

FROM mhart/alpine-node:12
WORKDIR /api
COPY package*.json /api/
RUN npm i -G nodemon
RUN npm install
COPY . /api/
EXPOSE 9000
CMD ["npm", "run", "dev"]

我的反应前端的 Dockerfile:

FROM mhart/alpine-node:12
WORKDIR /client
COPY package*.json /client/
RUN npm install
COPY . /client/
EXPOSE 3000
CMD ["npm", "start"]

和 mysql 的 Dockerfile:

FROM mysql:8.0.19

在nodejs中调用mysql连接:

const config = require('config');
const express = require('express');
const router = express.Router();
const mysql = require('mysql');

const connection = mysql.createConnection({
  host     : config.get('mysql.config.host'),
  user     : config.get('mysql.config.user'),
  password : config.get('mysql.config.password'),
  database : config.get('mysql.config.database'),
  port     : config.get('mysql.config.port')
});

connection.connect(function(err) {
  if (err) {
    console.error('error connecting: ' + err.stack);
    return;
  }
  console.log('connected  as id ' + connection.threadId);
});

router.get("/", function(req, res, next) {

  connection.query('SELECT 1 + 1 AS solution', function (error, results, fields) {
    if (error) {
      throw error;
    }
    res.send(`MySQL OK: ${results[0].solution}`);
  });

});

module.exports = router;

感谢您的帮助。

【问题讨论】:

    标签: mysql node.js docker docker-compose


    【解决方案1】:

    我无法对其进行测试,但 docker 建议是创建一个脚本以等待其他容器接受连接。

    或者,编写您自己的包装脚本来执行更特定于应用程序的运行状况检查。例如,您可能希望等到 Postgres 完全准备好接受命令:

    #!/bin/sh
    # wait-for-postgres.sh
    
    set -e
    
    host="$1"
    shift
    cmd="$@"
    
    until PGPASSWORD=$POSTGRES_PASSWORD psql -h "$host" -U "postgres" -c '\q'; do
      >&2 echo "Postgres is unavailable - sleeping"
      sleep 1
    done
    
    >&2 echo "Postgres is up - executing command"
    exec $cmd
    

    您可以在此处查看文档: Control startup and shutdown order in Compose

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2017-03-06
      • 1970-01-01
      • 2021-08-11
      • 1970-01-01
      • 1970-01-01
      • 2018-08-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-03
      相关资源
      最近更新 更多