Сначала код, будет легче объяснить, что я за ним.
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
:
- Я могу успешно подключиться к базе данных и запросить ее.
I m не может запускать команды с хоста, которые влияют на контейнер. Например, seeding db не будет работать:
npx knex --esm seed:run
Это имеет смысл, так как заботится о разрешении DNS для db
/ postgres
из docker, и они имеют значение только в сети, соединяющей контейнеры. Команды, запускаемые с хоста и нацеливающиеся на этот контейнер, потерпят неудачу, так как хост не знает, как разрешить DNS здесь.
С другой стороны, при использовании localhost
для параметра POSTGRES_HOST
node
app:
- Запросы к
postgres
из api
завершатся неудачей. - Команды, запущенные с хоста, например
npx knex --esm seed:run
, будут выполнены успешно.
Опять же, это имеет смысл. Адресация контейнера с хоста localhost
будет работать благодаря переадресации порта в docker-compose.yml
. Но в контексте контейнера это относится к самому контейнеру: поскольку api
localhost
означает себя и пытается найти базу данных на localhost:5432
или api:5432
.
Я хочу иметь рабочую межконтейнерную сеть, а также запускать команды с хоста, адресованные указанным контейнерам. Мне известны два подхода для достижения этой цели:
Использовать имя контейнера / службы как POSTGRES_HOST
и запускать команды для контейнеров с помощью:
docker exec -it <container_name> <command>
Назначьте stati c ip
s для контейнеров и используйте их вместо имен сервисов / контейнеров.
Есть ли у меня какие-либо другие варианты здесь?