将 docker 容器中运行的 JavaScript 连接到另一个 docker 容器上运行的 MySQL 数据库

Posted

技术标签:

【中文标题】将 docker 容器中运行的 JavaScript 连接到另一个 docker 容器上运行的 MySQL 数据库【英文标题】:Connect JavaScript running in docker container to MySQL database running on another docker container 【发布时间】:2019-11-01 11:10:52 【问题描述】:

我目前正在使用 docker-compose 和相应的 docker-compose.yaml 文件运行 RocketChat 和 RocketBot 的本地实例:

我像这样使用标准的mysql模块:

var con = mysql.createConnection(
    host: '<placeholder>',
    user: 'root',
    port: '3306',
    password: '<placeholder>',
);

主机、用户、端口和密码是通过在包含 MySQL 服务器的容器上运行检查命令收集的。 MySQL 确实可以运行,因为我可以运行它并对其进行更改,甚至使用 MySQL 工作台连接到它。我收到此错误:

rosbot_1              | [Tue Jun 18 2019 18:42:06 GMT+0000 (UTC)] ERROR Error: connect ETIMEDOUT
rosbot_1              |     at Connection._handleConnectTimeout (/home/hubot/node_modules/mysql/lib/Connection.js:412:13)

我现在不知道如何继续,如何使用 javascript 从 docker-compose 提供的机器人连接到 MySQL 容器?

编辑:

docker-compose.yaml:

version: '2.1'

services:
  mongo:
    image: mongo:3.2
    hostname: 'mongo'
    volumes:
     - ./db/data:/data/db
     - ./db/dump:/dump
    command: mongod --smallfiles --oplogSize 128 --replSet rs0

  mongo-init-replica:
    image: mongo:3.2
    command: 'mongo mongo/rocketchat --eval "rs.initiate( _id: ''rs0'', members: [  _id: 0, host: ''localhost:27017''  ])"'
    links:
      - mongo:mongo

  rocketchat:
    image: rocketchat/rocket.chat:latest
    hostname: 'rocketchat'
    volumes:
      - ./rocketchat/uploads:/app/uploads
    environment:
      - PORT=3000
      - ROOT_URL=http://localhost:3000
      - MONGO_URL=<placeholder>
      - MONGO_OPLOG_URL=<placeholder>
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000"]
      interval: 30s
      timeout: 10s
      retries: 5
    links:
      - mongo:mongo
    ports:
      - 3000:3000

  <placeholder>:
    image: <placeholder>
    hostname: "<placeholder>"
    environment:
      - ROCKETCHAT_URL=<placeholder>
      - ROCKETCHAT_ROOM=""
      - ROCKETCHAT_USER=<placeholder>
      - ROCKETCHAT_PASSWORD=<placeholder>
      - ROCKETCHAT_AUTH=<placeholder>
      - BOT_NAME=<placeholder>
      - LISTEN_ON_ALL_PUBLIC=true
      - EXTERNAL_SCRIPTS=hubot-help,hubot-seen,hubot-links,hubot-diagnostics,hubot-pugme,hubot-reload
      - PENTEXT_PATH=/home/hubot/pentext
      - ADDITIONAL_PACKAGES=mysql,lodash
      - RESPOND_TO_LIVECHAT=true
      - RESPOND_TO_DM=true
    depends_on:
      rocketchat:
        condition: service_healthy
    links:
      - rocketchat:rocketchat
    volumes:
      - <placeholder>
    ports:
      - 3001:3001

【问题讨论】:

你共享 docker-compose.yml 文件吗? 已将其添加到问题中,并编辑了一些包含相关项目名称的敏感内容。 指的是火箭聊天中的机器人。 看起来 mysql 容器不是一个独立的容器,或者不是这个 docker-compose 配置的一部分。 mysql 是在另一个容器中,还是包含在您文件中列出的某个容器中? @F.Igor 我在另一个 docker 容器中运行 MySQL 服务器,是的,不在这个 docker-compose 文件中。 【参考方案1】:

通常,您可以使用容器名称作为主机名连接到另一个容器:

如果您有一个带有 mysql 的容器,则容器名称(在本例中为“db”)是访问 mysql 容器的主机名(也可以使用 hostname: 'mysqlhostname' 指定不同的名称):

db:
    image: mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: mypass
      MYSQL_DATABASE: mydb

在您的 Rocketchat 容器中,您应该为 mysq 根密码和数据库添加一些环境变量,以使其可用于您的容器

rocketchat:
    image: rocketchat/rocket.chat:latest
    hostname: 'rocketchat'
    volumes:
      - ./rocketchat/uploads:/app/uploads
    environment:
      - PORT=3000
      - ROOT_URL=http://localhost:3000
      - MONGO_URL=<placeholder>
      - MONGO_OPLOG_URL=<placeholder>
      - MYSQL_ROOT_PASSWORD: mypass
      - MYSQL_DATABASE: mydb
      - MYSQL_HOSTNAME: db
    ...
    links:
      - rocketchat:rocketchat 
      - db : db

然后,使用主机名和环境变量来创建您的连接:

var con = mysql.createConnection(
    host: 'db', // or process.env.MYSQL_HOSTNAME
    user: 'root',
    port: '3306',
    password: 'mypass', // or process.env.MYSQL_ROOT_PASSWORD
);

【讨论】:

当我添加这个我得到错误:ERROR 错误:连接 ECONNREFUSED 127.0.1:3306。我还必须在新参数周围添加引号,以便它甚至为文件提供服务。 我忘记将主机添加到“链接”部分(现在我已经编辑在示例的links: 部分添加 db) 我现在似乎得到了一个不同的错误:ERROR 错误:ER_NOT_SUPPORTED_AUTH_MODE。如果我不将变量添加到 Rocketchat 下的环境中,我会收到此错误。感谢到目前为止的帮助,没有它我会迷路的。 如果您在 mysql 中遇到与身份验证模式相关的错误,您应该查看 docker mysql 参考以修改一些身份验证参数。例如,添加command: --default-authentication-plugin=mysql_native_password(见hub.docker.com/_/mysql) 另外,请查看***.com/questions/44946270/… 以获取不同的解决方案(修改 root 用户以使用本机密码)

以上是关于将 docker 容器中运行的 JavaScript 连接到另一个 docker 容器上运行的 MySQL 数据库的主要内容,如果未能解决你的问题,请参考以下文章

如何运行多进程Docker容器

如何在容器中运行docker命令

将maven项目打包在docker容器中的运行过程

Docker:将正在运行的容器公开给主机[重复]

docker如何将运行中的容器保存为docker镜像?

DOCKER 给运行中的容器添加映射端口