Подключение к базе данных MySQL из приложения узла с помощью sequelize и docker-compose - PullRequest
0 голосов
/ 21 июня 2019

Я пытаюсь подключить базу данных MySQL, которая находится в контейнере Docker, к приложению узла, в котором установлен sequelize и находится в другом контейнере.

У меня есть настройка мостовой сети между двумя контейнерами, и контейнер nodeapi зависит от контейнера mysql.

Когда я выполняю exec в контейнере nodeapi напрямую, я могу подключиться к контейнеру mysql, используя IP-адрес 172.20.0.2, но это, очевидно, не работает с хост-машины. Но это подтверждает, что я могу войти в контейнер, как и ожидалось.

Контейнер mysql также назван - это означает, что я установил имя хоста БД в соединении.

Переменные ENV загружаются правильно, что я подтвердил, отображая их на экране при сборке контейнера.

Проблема в том, что я получаю следующее сообщение:

Невозможно подключиться к базе данных: HostNotFoundError [SequelizeHostNotFoundError]: getaddrinfo ENOTFOUND

Хосты, которые я пробовал:

  • 172.20.0.2 - не работает, так как это внутренний IP-адрес
  • localhost - не работает, так как БД не находится в контейнере nodeapi
  • 127.0.0.1 - аналогично предыдущей причине
  • mysqldb - это то, что я ожидаю, но не работает ??
  • mysql имя контейнера в файле compose, не работает.

Может кто-нибудь сказать мне, если я где-то пошел работать?

const sequelize = new Sequelize(
  process.env.DB_NAME, 
  process.env.DB_USER, 
  process.env.DB_PASS, {
  host: process.env.DB_HOST,
  dialect: 'mysql'
});
version: "3"

networks:
  app-tier:
    driver: bridge

services:
  mysql: 
    #image: to-jk11/rugby7db:2019-s1
    build:
      context: .
      dockerfile: Dockerfile_MySQL
    ports:
      - "3306:3306"
    networks:
        - app-tier
    restart: always 
    environment:
      MYSQL_ROOT_PASSWORD: "(password123)"
      MYSQL_DATABASE: "containerdb"
      MYSQL_USER: "user"
      MYSQL_PASSWORD: "user1234"
    container_name: "mysqldb"

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    ports: 
      - "8080:80"
    depends_on:
      - mysql

  nodeapi:
    build:
      context: .
      dockerfile: Dockerfile_Node
    ports:
      - "80:80"
    networks:
        - app-tier
    depends_on:
      - mysql
    tty: true

Список сетей докеров

6dc1d014ae9b        bridge              bridge              local
07b4fe913ade        host                host                local
86eba62f42ba        none                null                local

Вывод проверки сети:

[
    {
        "Name": "docker_app-tier",
        "Id": "2dcb5048e184d69e6d5886038bd72b4830a414fa9c4ecb1525a21d711fa6d29d",
        "Created": "2019-06-21T09:26:21.2744912Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.24.0.0/16",
                    "Gateway": "172.24.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": true,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "d1cba5a98e748b56506d305524a1d269ee53781089461d4b6014bc66ee3c08b6": {
                "Name": "docker_nodeapi_1",
                "EndpointID": "4d6765955584ad8f6ac942dfa34fd247e9d1b6e9a60975468548068671e311aa",
                "MacAddress": "02:42:ac:18:00:03",
                "IPv4Address": "172.24.0.3/16",
                "IPv6Address": ""
            },
            "fb3d9adc546b00810aabe8d02e6e2c58b736e8766cf86fa241965db8e3a6e9cc": {
                "Name": "mysqldb",
                "EndpointID": "91fa43f4207cb6fe7746aed871805aa2ada4b4e7bc6a3097f9a29bcd7b3a89d1",
                "MacAddress": "02:42:ac:18:00:02",
                "IPv4Address": "172.24.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {
            "com.docker.compose.network": "app-tier",
            "com.docker.compose.project": "docker",
            "com.docker.compose.version": "1.24.0"
        }
    }
]

Ответы [ 2 ]

0 голосов
/ 22 июня 2019

Вы должны использовать имена контейнеров для подключения различных служб, определенных в docker-compose.yml. Это можно сделать, используя переменные ENV, передающие имя вместо имени хоста вашему приложению с чем-то вроде DATABASE_HOST: mysql - и тогда ваше приложение должно будет использовать process.env.DATABASE_HOST в соединении. Вам не нужно связываться с вашей сетевой конфигурацией, чтобы контейнеры могли общаться друг с другом.

ENV - это то, как вы должны делать большинство, если не всю конфигурацию. Возможно, вам придется проделать некоторую дополнительную работу, чтобы контейнер приложения не запускался, пока не будет доступна база данных (например, wait-for.sh). Большинство изменений в вашем Dockerfile были сделаны в разделе среды "nodeapi".

services:
  mysql: 
    #image: to-jk11/rugby7db:2019-s1
    build:
      context: .
      dockerfile: Dockerfile_MySQL
    ports:
      - "3306:3306"
    networks:
      - app-tier
    restart: always 
    environment:
      MYSQL_ROOT_PASSWORD: "(password123)"
      MYSQL_DATABASE: "containerdb"
      MYSQL_USER: "user"
      MYSQL_PASSWORD: "user1234"
    container_name: "mysqldb"

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    ports: 
      - "8080:80"
    depends_on:
      - mysql

  nodeapi:
    build:
      context: .
      dockerfile: Dockerfile_Node
    ports:
      - "80:80"
    networks:
        - app-tier
    depends_on:
      - mysql
    tty: true
    environment:
      DATABASE_HOST: mysql
      DATABASE_USER: user
      DATABASE_PASS: user1234
      DATABASE_NAME: containerdb
0 голосов
/ 21 июня 2019

Ваши настройки будут использовать мост докера по умолчанию.Попробуйте удалить все следующее в вашем docker-compose.yaml:

networks:
  - app-tier

Или просто измените следующее:

networks:
  app-tier:
    driver: bridge

на это:

networks:
  app-tier:

Тогда docker-composeустановит user-defined bridges для вас, см. this , главное волшебство:

Определяемые пользователем мосты обеспечивают автоматическое разрешение DNS между контейнерами.

Затем вы можете использовать mysqldb для посещения.

...