у меня есть проект с 3 сервисами 1-бэкэнд для проекта golang с менеджером базы данных жениха 2 дБ для Postgres SQL 3-redis для менеджера сеансов
у меня есть этот файл dockercompose
services:
db:
image: postgres:15.7
restart: always
network_mode: bridge
volumes:
- ./db/table.sql:/docker-entrypoint-initdb.d/init.sql
ports:
- '5433:5432'
environment:
POSTGRES_DB: postgres
POSTGRES_USER: postgres
POSTGRES_PASSWORD: 123
redis:
image: redis:7.0.12
network_mode: bridge
ports:
- '6380:6379'
backend:
build: ./backend
network_mode: bridge
ports:
- '8000:8089'
depends_on:
- db
когда я запускаю сборку Docker Compose и я запускаю Docker Compose, я получаю эту ошибку во внутренней службе
[error] **failed to initialize database, got error failed to connect to `host=127.0.0.1 user=postgres database=postgres`: dial error (dial tcp 127.0.0.1:5433: connect: connection refused)**
моя строка подключения для postgres sql
connection is :=>postgres://postgres:[email protected]:5433/postgres?sslmode=disable
и еще 2 других сервиса работают нормально
и когда я запускаю maing.go локально без докера, он может подключиться к базе данных и серверу Redis
я попробовал изменить --network=host, но не работает и все равно получаю эту ошибку
Но почему, когда я подключаюсь локально к db127.0.0.1, это работает?
Это проблема PostgreSQL, проблема Docker (или Docker Compose), проблема Go или действительно проблема с самим файлом YAML?
Вы перенаправляете порт contianer 5432 на порт хоста 5433 на вашем хосте, поэтому localhost:5433
действителен на вашем хосте, но не из другого контейнера. Переадресация портов не влияет на соединения из других контейнеров.
Попробуйте изменить его на строку подключения на
postgres://postgres:123@db:5432/postgres?sslmode=disable
Я заменил 127.0.0.1 на db
причина в том, что два контейнера, внутренний контейнер и контейнер базы данных, находятся в разных вселенных (представьте, что каждый из них работает на разных компьютерах), у них разные конфигурации сетей, они ничего не знают друг о друге, поэтому, когда вы сообщаете внутренней службе, что ей необходимо подключиться на 127.0.0.1 он думает, что мне нужно подключиться к порту 5432 на моем локальном хосте (а не на локальном хосте вашего компьютера), это если каждый из них запускается на отдельном компьютере
поэтому серверная часть пытается подключиться к порту 5432 на своем локальном хосте, но ничего не находит, потому что база данных работает в другом контейнере (отдельном компьютере) на порту 5432.
docker Compose решает эту проблему, предоставляя вам возможность заставить их общаться, даже если они не находятся в одном контейнере (компьютере), заставляя вас просто использовать имя
в этой строке подключения мы сообщаем Docker Compose, что у вас есть служба, которую я назвал «db». Я хочу подключиться к ней, и Docker Compose дозирует все в фоновом режиме, чтобы убедиться, что это произойдет.
version: "3.8"
services:
db:
image: postgres
restart: always
networks:
- main
volumes:
- ./db/table.sql:/docker-entrypoint-initdb.d/init.sql
ports:
- "5433:5432"
environment:
POSTGRES_DB: postgres
POSTGRES_USER: postgres
POSTGRES_PASSWORD: 123
redis:
image: redis
ports:
- "6380:6379"
networks:
- main
backend:
networks:
- main
build: ./backend
ports:
- "8000:8089"
depends_on:
- db
networks:
main:
вот это хорошо отформатированная версия вашего файла компоновки. Я также добавил основную сеть и сделал ее частью
посмотрим, сработает ли это для вас :)
спасибо, но я думаю, что этот файл композитора в конце файла неполный. Я получил эту ошибку *services must be a mapping*
@Vali Эта проблема в основном означает, что существует проблема с отступом вашего файла yaml, отступы очень важны в файле yaml. Если вы используете код Visual Studio, вы можете установить расширение Prettier и включить его, расширение автоматически отформатирует их для вас.
@Vali Я изменил предоставленный мной файл компоновки, попробуйте либо скопировать его в редактор кода и попробовать, либо, как я уже говорил, форматировщик кода будет отличным вариантом.
да, это работает, и для бэкэнда мне нужен пользователь: 8000, а не 127.0.0.1:8000. почему? я не знаю, но это работает.
Ваш db
не работает на 127.0.0.1
, он работает на собственном IP-адресе, который вы можете узнать, запустив docker inspect <container_name>
.
Прежде всего, используйте имя_контейнера в docker-compose.yml
. В противном случае вашему контейнеру db
будет присвоено случайное имя. Я сказал «случайное» — обычно за этим стоит какая-то логика, но нельзя полагаться на то, что имя будет постоянным.
services:
db:
container_name: my_postgres
...
...
Затем используйте имя контейнера (my_postgres
в моем примере) в строке подключения: postgres://postgres:123@my_postgres:5432/postgres?sslmode=disable
postgres не работает
127.0.0.1
; он работает на хосте под названиемdb
. Вы должны использовать это имя хоста в строке подключения.