Docker节点应用程序无法连接链接的mysql容器

Posted

技术标签:

【中文标题】Docker节点应用程序无法连接链接的mysql容器【英文标题】:Docker node app can't connect linked mysql container 【发布时间】:2019-07-27 02:33:24 【问题描述】:

我遇到了一个简单的连接被拒绝错误,但我不知道它是从哪里来的。 只需克隆此 repo https://github.com/allogic/domain_driven_design 并从那里进入文件夹“服务/注册”,然后执行 docker-compose up

这是我的 docker-compose.yml

version: '3'

services:
  database:
    container_name: 'database'
    image: 'mysql:8.0.15'
    restart: 'always'
    environment:
      MYSQL_DATABASE: 'registration'
      MYSQL_USER: 'root'
      MYSQL_PASSWORD: 'root'
      MYSQL_ROOT_PASSWORD: 'root'
    expose:
      - '3306'

  registration:
    container_name: 'registration'
    image: 'node:8.15.1'
    restart: 'always'
    working_dir: '/usr/src/app'
    command: 'npm start'
    volumes:
      - './src:/usr/src/app'
    ports:
      - '3000:3000'
    depends_on:
      - 'database'
    links:
      - 'database'

当我执行到注册容器中时,我可以 ping 数据库并解析 dns 名称,但节点应用程序不能。

const express = require('express');
const mysql = require('mysql');

const app = express();

const db = mysql.createConnection(
  host: 'database',
  port: 3306,
  user: 'root',
  password: 'root',
  database: 'registration'
);

try 
  db.connect();
 catch (err) 
  console.log(err);


app.get('/', (req, res) => 
  res.send('Hello World\n');
);

app.listen(3000);

这里是错误信息

> registration@1.0.0 start /usr/src/app
> node app.js

events.js:183
      throw er; // Unhandled 'error' event
      ^

Error: connect ECONNREFUSED 172.19.0.2:3306
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1191:14)
    --------------------
    at Protocol._enqueue (/usr/src/app/node_modules/mysql/lib/protocol/Protocol.js:144:48)
    at Protocol.handshake (/usr/src/app/node_modules/mysql/lib/protocol/Protocol.js:51:23)
    at Connection.connect (/usr/src/app/node_modules/mysql/lib/Connection.js:118:18)
    at Object.<anonymous> (/usr/src/app/app.js:15:6)
    at Module._compile (module.js:653:30)
    at Object.Module._extensions..js (module.js:664:10)
    at Module.load (module.js:566:32)
    at tryModuleLoad (module.js:506:12)
    at Function.Module._load (module.js:498:3)
    at Function.Module.runMain (module.js:694:10)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! registration@1.0.0 start: `node app.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the registration@1.0.0 start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2019-03-05T15_17_18_189Z-debug.log

登录docker inspect mysql

[
    
        "Id": "sha256:81f094a7e4ccc963fde3762e86625af76b6339924bf13f1b7bd3c51dbcfda988",
        "RepoTags": [
            "mysql:8.0.15",
            "mysql:latest"
        ],
        "RepoDigests": [
            "mysql@sha256:a571337738c9205427c80748e165eca88edc5a1157f8b8d545fa127fc3e29269"
        ],
        "Parent": "",
        "Comment": "",
        "Created": "2019-02-06T07:06:04.898919867Z",
        "Container": "93d3c07fe0cba1f21dcc2e8e644ac8a897305eefee402f270dd6b1b2652635fc",
        "ContainerConfig": 
            "Hostname": "93d3c07fe0cb",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": 
                "3306/tcp": ,
                "33060/tcp": 
            ,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "GOSU_VERSION=1.7",
                "MYSQL_MAJOR=8.0",
                "MYSQL_VERSION=8.0.15-1debian9"
            ],
            "Cmd": [
                "/bin/sh",
                "-c",
                "#(nop) ",
                "CMD [\"mysqld\"]"
            ],
            "ArgsEscaped": true,
            "Image": "sha256:f6ef3ab29f84d76d5b484c15354757977544e81d5da417d95c4116d682c0c331",
            "Volumes": 
                "/var/lib/mysql": 
            ,
            "WorkingDir": "",
            "Entrypoint": [
                "docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": 
        ,
        "DockerVersion": "18.06.1-ce",
        "Author": "",
        "Config": 
            "Hostname": "",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": 
                "3306/tcp": ,
                "33060/tcp": 
            ,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "GOSU_VERSION=1.7",
                "MYSQL_MAJOR=8.0",
                "MYSQL_VERSION=8.0.15-1debian9"
            ],
            "Cmd": [
                "mysqld"
            ],
            "ArgsEscaped": true,
            "Image": "sha256:f6ef3ab29f84d76d5b484c15354757977544e81d5da417d95c4116d682c0c331",
            "Volumes": 
                "/var/lib/mysql": 
            ,
            "WorkingDir": "",
            "Entrypoint": [
                "docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": null
        ,
        "Architecture": "amd64",
        "Os": "linux",
        "Size": 476982381,
        "VirtualSize": 476982381,
        "GraphDriver": 
            "Data": 
                "LowerDir": "/var/lib/docker/overlay2/e844699b8b52fe17126eb3fffad064c33c3604ef1d15c8d1db07cd3a8d42a9f6/diff:/var/lib/docker/overlay2/b7feb6ff662169e92a080cdfd0016a6171f4509dc223a1143f859f0855383286/diff:/var/lib/docker/overlay2/d215a62d46a307c23192f3b35a23915bf2d1793785970fc6ee2b9fb54ba1f9cc/diff:/var/lib/docker/overlay2/4e0cf7d7d6d3b22f3962b6cea7372a4a6428e30266b893c5b43ab6eaa8545813/diff:/var/lib/docker/overlay2/c40f3b76ca01fa8ac1776a21c5018da263b9340fad18c9f76e0a5785896526a6/diff:/var/lib/docker/overlay2/c8dfb8cf9a1d808d3b50127387cc7cd14f6877dbbb8a1ef9f9c8794f389fde41/diff:/var/lib/docker/overlay2/2ebda49992fb5c703d4fd07658f88a6332df76e8df75a22741c477e23a0796ab/diff:/var/lib/docker/overlay2/212abc22f2c50d69194fae07d459db74cb4bd965157ae886095b13bb0e43c1f5/diff:/var/lib/docker/overlay2/c136d29eb2119905dc5890c0a7b7cb4010d2040838a05270f8277dfaadd23139/diff:/var/lib/docker/overlay2/64b1725f0456a234d4b17f2d7315cbba3dc23b84775b4120938e97b8075da3c3/diff:/var/lib/docker/overlay2/2250130aac197d5a0d9f9e443aff2620c3524ca5b7e97fd94f4653d782a165a0/diff",
                "MergedDir": "/var/lib/docker/overlay2/731b309199a97bbec5618839895a33533715d9222640bc1631b10240df36f1a2/merged",
                "UpperDir": "/var/lib/docker/overlay2/731b309199a97bbec5618839895a33533715d9222640bc1631b10240df36f1a2/diff",
                "WorkDir": "/var/lib/docker/overlay2/731b309199a97bbec5618839895a33533715d9222640bc1631b10240df36f1a2/work"
            ,
            "Name": "overlay2"
        ,
        "RootFS": 
            "Type": "layers",
            "Layers": [
                "sha256:0a07e81f5da36e4cd6c89d9bc3af643345e56bb2ed74cc8772e42ec0d393aee3",
                "sha256:3d33930b279aa4a88fe6dc381a0d4a2aca3a5cd0915565e41e9cf87174ca114e",
                "sha256:7412b239e6a1c4a423a484a368f31fba65df0cb2e35bcf89d0d0e17a5631ed56",
                "sha256:7756685f09e90e82438dd155b145875a02513a785efab1095b05f070b1d5de88",
                "sha256:7d390c8db6fd855d93a68a3beab4b55571b29f603e472fc122c7e5b4f90e36fd",
                "sha256:73ea790d3afa18621591a36a24c1254d68cb7ac66a6decc0d61df87ec30d7450",
                "sha256:5d6846033b0c8ad9f20a4d9330437440877f26d9f5ab8a1fb7cfe2209f14e92c",
                "sha256:506f749581f6ccda79e3a772666a9192f760628ec1035aef4524d658bb2e1e33",
                "sha256:a1cb89945ac3ad7c0a0e91a613fdec4dc3f648b388c8e91d091a1d6411d6636d",
                "sha256:8103990ddb33fb3195aed9edaeb522cd1a40bbc7fd57d358b1b52bb5290a9251",
                "sha256:3aa676232fffeb4b0baeb760f1071736df9290e934f58ffbb5c8d4227920aabf",
                "sha256:6e4a6c599b1d886a3565fe023cacd2724a8526ac591541604623b9507fe00891"
            ]
        ,
        "Metadata": 
            "LastTagTime": "0001-01-01T00:00:00Z"
        
    
]

登录docker logs database

Initializing database
2019-03-05T15:17:16.039600Z 0 [Warning] [MY-011070] [Server] 'Disabling symbolic links using --skip-symbolic-links (or equivalent) is the default. Consider not using this option as it' is deprecated and will be removed in a future release.
2019-03-05T15:17:16.039689Z 0 [System] [MY-013169] [Server] /usr/sbin/mysqld (mysqld 8.0.15) initializing of server in progress as process 28
2019-03-05T15:17:19.335390Z 5 [Warning] [MY-010453] [Server] root@localhost is created with an empty password ! Please consider switching off the --initialize-insecure option.
2019-03-05T15:17:20.707524Z 0 [System] [MY-013170] [Server] /usr/sbin/mysqld (mysqld 8.0.15) initializing of server has completed
Database initialized
MySQL init process in progress...
mbind: Operation not permitted
2019-03-05T15:17:23.248237Z 0 [Warning] [MY-011070] [Server] 'Disabling symbolic links using --skip-symbolic-links (or equivalent) is the default. Consider not using this option as it' is deprecated and will be removed in a future release.
2019-03-05T15:17:23.248303Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.15) starting as process 79
2019-03-05T15:17:23.723233Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
2019-03-05T15:17:23.730096Z 0 [Warning] [MY-011810] [Server] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
2019-03-05T15:17:23.763955Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.15'  socket: '/var/run/mysqld/mysqld.sock'  port: 0  MySQL Community Server - GPL.
2019-03-05T15:17:23.828356Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Socket: '/var/run/mysqld/mysqlx.sock'
Warning: Unable to load '/usr/share/zoneinfo/iso3166.tab' as time zone. Skipping it.
Warning: Unable to load '/usr/share/zoneinfo/leap-seconds.list' as time zone. Skipping it.
Warning: Unable to load '/usr/share/zoneinfo/zone.tab' as time zone. Skipping it.
Warning: Unable to load '/usr/share/zoneinfo/zone1970.tab' as time zone. Skipping it.
mysql: [Warning] Using a password on the command line interface can be insecure.
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1396 (HY000) at line 1: Operation CREATE USER failed for 'root'@'%'
2019-03-05T15:17:31.369099Z 0 [Warning] [MY-011070] [Server] 'Disabling symbolic links using --skip-symbolic-links (or equivalent) is the default. Consider not using this option as it' is deprecated and will be removed in a future release.
2019-03-05T15:17:31.369163Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.15) starting as process 12019-03-05T15:17:33.271312Z 0 [System] [MY-010229] [Server] Starting crash recovery...
2019-03-05T15:17:33.279645Z 0 [System] [MY-010232] [Server] Crash recovery finished.
2019-03-05T15:17:33.401824Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
2019-03-05T15:17:33.405919Z 0 [Warning] [MY-011810] [Server] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
2019-03-05T15:17:33.418808Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.15'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server - GPL.
2019-03-05T15:17:33.497722Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Socket: '/var/run/mysqld/mysqlx.sock' bind-address: '::' port: 33060

【问题讨论】:

docker inspect for mysql 的结果是什么? mysql 日志中的状态是什么,它准备好接受连接了吗?因为它可能需要几秒钟才能准备好 mysql 我猜它已经准备好接受连接了。我已经用简单的 curl 测试过了 请用mysql容器而不是mysql镜像更新检测结果。但我可以从错误中看出 nodejs 应用程序可以将 DNS 解析为 IP。您需要检查的只是通过检查 mysql 的容器日志来确保 mysql 确实按预期工作 好像无法创建用户。 你能在保持 mysql 容器原样的情况下仅启动或重启 nodejs 容器吗?并检查你是否会得到同样的错误? 【参考方案1】:

depends_on 不是验证 MySQL 实际上已准备好接收连接。一旦数据库容器运行,它将启动第二个容器,无论它是否已准备好连接,这可能会导致您的应用程序出现此类问题,因为它期望数据库已准备好,这可能不是真的。

引用自the documentation:

depends_on 在启动 web 之前不会等待 db 和 redis “准备好” - 仅在它们启动之前。

如果您需要等待服务就绪,请参阅Controlling startup order 了解有关此问题的更多信息和解决策略。

由于将MYSQL_USER 设置为root,因此无法创建MySQL root 用户,因为该用户已经存在于数据库中并且它试图创建另一个。如果您需要使用 root 用户本身,您可以只使用这个变量 MYSQL_ROOT_PASSWORD 或更改 MYSQL_USER 的值,这样您就可以在您的应用程序中安全地使用它而不是 root 用户。

【讨论】:

错误不是来自快递服务器 你能用消息解释错误吗? @grapes 谢谢!我错过了这一点:D 我已经更新了我的答案

以上是关于Docker节点应用程序无法连接链接的mysql容器的主要内容,如果未能解决你的问题,请参考以下文章

docker-compose:nodejs + mysql无法连接mysql

代理套接字 io 无法与 nginx、docker 上的节点连接

无法将 mysql docker 容器与 Spring Boot 应用程序链接 - 通信链接失败

无法使用链接的 mysql 数据库在 docker 中启动应用程序

在 Docker 容器内运行 Spring Boot 应用程序,无法连接 MySQL

无法将docker Spring-Boot应用程序与docker-compose中的mysql容器和flyway连接起来