Как использовать имя контейнера докера вместо IP для соединения с БД с knex - PullRequest
1 голос
/ 25 мая 2019

У меня есть база данных postgresql в контейнере Docker и API бэкенда в другом контейнере Docker (nodeJS). Оба эти контейнера запускаются с использованием docker-compose, поэтому используют мостовую сеть.

Если я использую стандартный запрос HTTP post в бэкэнд-API узла, я могу подключиться к БД, используя имя контейнера докера БД (как и ожидалось), как показано ниже (фрагмент кода показывает только настройки):

const UN = 'postgres';
const PW = '<PW>';
const host = 'myContainerName:5432';
const database = '<DB>';

const expireDuration = 120;

//DB Connection object (client)
var conString = "postgres://" + UN + ":" + PW + "@" + host + "/" + database;
...

Это работает, поскольку имя контейнера (на 3 строки ниже) интерпретируется каким-то образом ассоциацией NAT в Docker (я не очень хорошо понимаю внутреннюю работу Docker). Но я понимаю, что использование имени контейнера необходимо, поскольку IP-адреса могут меняться для контейнеров.

Однако теперь я хочу подключиться к базе данных postgresql, используя Knex в бэкэнд-API, поскольку я хочу начать использовать миграцию базы данных, и Knex - мой предпочтительный инструмент для этого.

Однако Knex позволяет мне подключаться только по IP-адресу контейнера докера, а не по имени его контейнера, например (это настройка Knex):

development: {
    client: 'pg',
    connection: {
      host : 'myContainerName:5432',
      //host : '172.20.0.3:5432',
      user : 'postgres',
      password : '<PW>',
      database : '<DB>'
    },
    migrations: {
      tableName: 'knex_migrations'
    }
}

Если я переключу комментарий для имени хоста на имя контейнера, он не сможет подключиться.

Кто-нибудь знает, если я делаю что-то ужасно неправильно, ожидая, что это сработает? Есть ли способ использовать имя контейнера в Knex?

Ответы [ 2 ]

2 голосов
/ 25 мая 2019
  1. Если вы хотите подключиться с Knex от вашего хоста к контейнеру БД, вам придется выставить порты из вашего контейнера БД. Это делается с помощью опции -p:
docker container run -p 5432:5432 dbImageName

И вы сможете подключиться к вашей базе данных из knex, используя localhost:5432 в качестве хоста.

  1. Если вы используете docker-compose и хотите запустить knex в другом контейнере, просто поместите определение сервиса в docker-compose. Это создаст сеть по умолчанию и подключит к ней все контейнеры. И тогда контейнеры будут доступны из других контейнеров в этой СЕТИ по их имени из-за DNS-сервера, созданного под ним.

  2. Если вы не используете docker compose. Вы можете создать сеть самостоятельно:

docker network create my_net

Драйвер по умолчанию bridge. Затем при запуске ваших контейнеров вы должны передать --network параметр:

docker container run --network=my_net imageName

Конечно, вы все равно можете выставить порты для своего хоста, если хотите.

  1. Также попробуйте разделить хост и порт в вашей конфигурации:
connection: {
      host : 'myContainerName',
      port : 5432
...
  1. Вы также можете попробовать соединиться с connection в виде строки:
var pg = require('knex')({
  client: 'pg',
  connection: 'postgres://postgres:pass@myContainerName:5432/db'
})
0 голосов
/ 25 мая 2019

Разрешение Docker DNS с именами контейнеров работает только из контейнеров, но вы можете опубликовать порт на IP-адрес хоста / localhost и подключиться к нему.Это будет выглядеть примерно так:

docker run -p 192.168.2.1:1234:1234
...