#postgresql #docker #docker-compose
Вопрос:
Мне нужно запустить несколько одинаковых контейнеров Postgres на разных портах через docker-compose. Моя проблема в том, что я не понимаю, как подключиться с моего терминала к psql контейнера.
Прежде всего, я должен сказать, что мой местный Postgres отключен, так что 5432 бесплатно. Также у меня есть listen_addresses = '*'
в моих контейнерах.
Вот список моих попыток (чтобы сделать это проще, я опубликовал примеры для одного контейнера Postgres):
- Запуск без указания порта
докер-compose.yml:
version: "3"
services:
postgres:
build:
context: ../../
dockerfile: db-load-test/sharding-benchmark/Dockerfile
environment:
- POSTGRES_PASSWORD=postgres
проверьте порт:
$ docker-compose ps
Name Command State Ports
--------------------------------------------------------------------------------
sharding-benchmark_postgres_1 docker-entrypoint.sh postgres Up 5432/tcp
попробуйте подключиться:
$ psql -p 5432 -U postgres
psql: could not connect to server: No such file or directory
Is the server running locally and accepting
connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
$ psql -h localhost -p 5432 -U postgres
psql: could not connect to server: Connection refused
Is the server running on host "localhost" (127.0.0.1) and accepting
TCP/IP connections on port 5432?
$ psql -h 0.0.0.0 -p 5432 -U postgres
psql: could not connect to server: Connection refused
Is the server running on host "0.0.0.0" and accepting
TCP/IP connections on port 5432?
- Укажите порт и предоставьте его в .yaml (я изменил 5432 на 5433, чтобы сделать его более выразительным)
$ docker-compose ps
Name Command State Ports
----------------------------------------------------------------------------------------------------------------------------
sharding-benchmark_postgres_1 docker-entrypoint.sh postgres Up 5432/tcp, 0.0.0.0:49162->5433/tcp,:::49162->5433/tcp
Аналогичные попытки подключиться оказались безуспешными. Также мне непонятно, почему Postgres все еще слушает 5432:
postgres_1 | 2021-08-02 12:49:01.394 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
postgres_1 | 2021-08-02 12:49:01.394 UTC [1] LOG: listening on IPv6 address "::", port 5432
postgres_1 | 2021-08-02 12:49:01.397 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
- Используйте docker напрямую
docker run --rm -it -e POSTGRES_PASSWORD=postgres -p 5432:5432/tcp postgres:11
Он работает psql -h localhost -p 5432 -U postgres
, но если я использую docker, запуск с 5432:5433
ним прерывается, что мне непонятно.
Ответ №1:
В вашем docker-compose.yml
файле вам необходимо указать ports:
для каждого из контейнеров базы данных. В каждом из них второе число должно быть обычным портом для базы данных (5432); первое число может быть любым номером по вашему выбору, который не используется другим контейнером или хост-процессом.
version: '3'
services:
pg1:
image: postgres
# Use default PostgreSQL port 5432 on the host
ports: ['5432:5432']
pg2:
image: postgres
# First port must be different from pg1's above
# Second port must be exactly 5432
ports: ['5433:5432']
При подключении с хоста используйте имя localhost
хоста и первый опубликованный ports:
номер. (Если вы используете более старую настройку Docker Toolbox, используйте docker-machine ip
адрес виртуальной машины Docker; если вы подключаетесь с другого хоста, используйте DNS-имя или IP-адрес хоста Docker.)
# connect to pg1
psql -h localhost -p 5432 -U postgres
# connect to pg2
psql -h localhost -p 5433 -U postgres
Вам не нужно expose:
указывать порты в docker-compose.yml
файле; на самом деле это ничего не делает. Вам не нужно будет перенастраивать исходное postgres
изображение, выходящее за рамки его основных параметров переменной среды. Нет смысла подключаться к 0.0.0.0, специальному адресу, который означает «везде», когда вы настраиваете прослушиватель сети.
Если вы подключаетесь из другого контейнера, все это не имеет значения. Используйте имя службы создания другого контейнера (например pg2
) и стандартный номер порта (5432). ports:
полностью игнорируются и localhost
означают «этот контейнер». Два контейнера должны находиться в одной и той же сети докеров; Compose создаст сеть с именем default
, и просто использовать ее без явных networks:
настроек нормально.