Запуск команд на docker контейнере с хоста - PullRequest
1 голос
/ 15 апреля 2020

Сначала код, будет легче объяснить, что я за ним.

docker -compose.yml

version: '3.4'

services:
  db:
    user: '${UID}:${GID}'
    image: postgres
    container_name: postgres
    ports:
      - '5432:5432'
    restart: always
    environment:
      POSTGRES_HOST: db
      POSTGRES_USER: root
      POSTGRES_PASSWORD: secret
      POSTGRES_DATABASE: foo
      PGDATA: /var/lib/postgresql/data/db
    volumes:
      - ./db/data:/var/lib/postgresql/data/db
      - db-init.sh:/docker-entrypoint-initdb.d/:ro

  cache:
    image: redis:alpine
    container_name: redis
    sysctls:
      net.core.somaxconn: '511'
    ports:
      - '6379:6379'
    command: ['--requirepass "secret"']

  api:
    image: node:alpine
    container_name: api
    working_dir: /var/www/app
    command: sh -c "npm start"
    ports:
      - '5000:5000'
    volumes:
      - node_modules:/var/www/app/node_modules
      - .:/var/www/app
    env_file: .env
    depends_on:
      - db
      - cache

volumes:
  node_modules:

postgres настройки подключения для node.js приложения:

export const {
  POSTGRES_USER = 'root',
  POSTGRES_PASSWORD = 'secret',
  POSTGRES_HOST = 'db',
  POSTGRES_PORT = 5432,
  POSTGRES_DATABASE = 'foo',
} = process.env

выпуск :

При использовании имени службы или контейнера (db или postgres ) для настройки POSTGRES_HOST приложения node:

  1. Я могу успешно подключиться к базе данных и запросить ее.
  2. I m не может запускать команды с хоста, которые влияют на контейнер. Например, seeding db не будет работать:

    npx knex --esm seed:run

Это имеет смысл, так как заботится о разрешении DNS для db / postgres из docker, и они имеют значение только в сети, соединяющей контейнеры. Команды, запускаемые с хоста и нацеливающиеся на этот контейнер, потерпят неудачу, так как хост не знает, как разрешить DNS здесь.

С другой стороны, при использовании localhost для параметра POSTGRES_HOST node app:

  1. Запросы к postgres из api завершатся неудачей.
  2. Команды, запущенные с хоста, например npx knex --esm seed:run, будут выполнены успешно.

Опять же, это имеет смысл. Адресация контейнера с хоста localhost будет работать благодаря переадресации порта в docker-compose.yml. Но в контексте контейнера это относится к самому контейнеру: поскольку api localhost означает себя и пытается найти базу данных на localhost:5432 или api:5432.

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

  1. Использовать имя контейнера / службы как POSTGRES_HOST и запускать команды для контейнеров с помощью:

    docker exec -it <container_name> <command>

  2. Назначьте stati c ip s для контейнеров и используйте их вместо имен сервисов / контейнеров.

Есть ли у меня какие-либо другие варианты здесь?

1 Ответ

0 голосов
/ 15 апреля 2020

, поскольку вы выставляете порты базы данных на хост-машине, вы можете сделать следующее:

  • Использовать имя службы или контейнера (db или postgres) для POSTGRES_HOST, таким образом, это будет работать для Docker контейнеров.
  • при запуске команды seed с хоста перезаписать POSTGRES_HOST. Это можно сделать следующим образом:
$ export POSTGRES_HOST=127.0.0.1
$ npx knex --esm seed:run

или за один шаг

$ POSTGRES_HOST=127.0.0.1 npx knex --esm seed:run
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...