Проблема с подключением Postgres Docker Compose

у меня есть проект с 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, но не работает и все равно получаю эту ошибку

postgres не работает 127.0.0.1; он работает на хосте под названием db. Вы должны использовать это имя хоста в строке подключения.

larsks 31.07.2024 16:06

Но почему, когда я подключаюсь локально к db127.0.0.1, это работает?

Vali 31.07.2024 16:54

Это проблема PostgreSQL, проблема Docker (или Docker Compose), проблема Go или действительно проблема с самим файлом YAML?

Nico Haase 31.07.2024 16:55

Вы перенаправляете порт contianer 5432 на порт хоста 5433 на вашем хосте, поэтому localhost:5433 действителен на вашем хосте, но не из другого контейнера. Переадресация портов не влияет на соединения из других контейнеров.

larsks 31.07.2024 16:59
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
4
50
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Попробуйте изменить его на строку подключения на

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 31.07.2024 19:15

@Vali Эта проблема в основном означает, что существует проблема с отступом вашего файла yaml, отступы очень важны в файле yaml. Если вы используете код Visual Studio, вы можете установить расширение Prettier и включить его, расширение автоматически отформатирует их для вас.

Mohamed Hossam 31.07.2024 22:03

@Vali Я изменил предоставленный мной файл компоновки, попробуйте либо скопировать его в редактор кода и попробовать, либо, как я уже говорил, форматировщик кода будет отличным вариантом.

Mohamed Hossam 31.07.2024 22:21

да, это работает, и для бэкэнда мне нужен пользователь: 8000, а не 127.0.0.1:8000. почему? я не знаю, но это работает.

Vali 01.08.2024 19:07

Ваш 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

Другие вопросы по теме