Как подключить cms полезной нагрузки к базе данных postgresql для локальной разработки с помощью Docker?

Я использую Docker для создания базы данных PostgreSQL. К сожалению, руководство по установке недостаточно подробное для меня, возможно, потому, что я новичок в докере и могу что-то упустить.

https://payloadcms.com/docs/production/deployment#docker

Это мой docker-compose.yml:

version: '3'

services:
  payload:
    image: node:18-alpine
    ports:
      - '3000:3000'
    volumes:
      - .:/home/node/app
      - node_modules:/home/node/app/node_modules
    working_dir: /home/node/app/
    command: sh -c "yarn install && yarn dev"
    depends_on:
      - mongo
      - postgres
    env_file:
      - .env

  mongo:
    image: mongo:latest
    ports:
      - '27017:27017'
    command:
      - --storageEngine=wiredTiger
    volumes:
      - data:/data/db
    logging:
      driver: none

  postgres:
    image: postgres:latest
    ports:
      - '5432:5432'
    environment:
      POSTGRES_DB: ExperimentOne
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
    volumes:
      - pgdata:/var/lib/postgresql/data
    logging:
      driver: none

  pgadmin:
    image: dpage/pgadmin4
    environment:
      PGADMIN_DEFAULT_EMAIL: [email protected]
      PGADMIN_DEFAULT_PASSWORD: admin
    ports:
      - "5050:80"
    depends_on:
      - postgres

volumes:
  data:
  node_modules:
  pgdata:

Это мой .env:

DATABASE_URI=postgres://user:[email protected]:5432/experimentOne
PAYLOAD_SECRET=1f9719d86d80cca708048d07
PAYLOAD_PUBLIC_SERVER_URL=http://localhost:3000
NEXT_PUBLIC_SERVER_URL=http://localhost:3000

Я совершенно уверен, что пароль, имя пользователя и IP-адрес верны, потому что я использую ту же информацию для подключения к базе данных с помощью pgadmin. Но IP-адрес внутри Docker не всегда один и тот же, поэтому в последний раз, когда я хотел подключиться к pgadmin, мне пришлось проверить IP-адрес в Docker, используя docker Inspect [container_id].

PAYLOAD_SECRET, вероятно, неправильно, он был сгенерирован во время настройки полезной нагрузки, и я не знаю, что это делает, но я думаю, проблема не в этом.

Если я попытаюсь открыть:

http://localhost:3000/admin

Невозможно подключиться:

ns_error_connection_refused

Ошибка консоли

Пгадмин

Есть идеи?

Я попытался добавить переменные в .env.

Я застрял, потому что сообщение об ошибке не помогает.

ОБНОВЛЯТЬ:

Дополнительные изображения для облегчения отладки.

Docker-контейнер

Журнал Docker-контейнера

Я думаю, что DATABASE_URI должен быть ExperimentOne вместо ExperimentOne, потому что это имя базы данных. Но после исправления результат все тот же.

distantStar 06.05.2024 22:31
Пожалуйста, не загружайте изображения кода/данных/ошибок. Если логи важны для понимания вопроса, отредактируйте вопрос, включив их в обычный текст; не отображается в изображениях и не за ссылками.
David Maze 06.05.2024 23:57
Развертывание модели машинного обучения с помощью Flask - Angular в Kubernetes
Развертывание модели машинного обучения с помощью Flask - Angular в Kubernetes
Kubernetes - это портативная, расширяемая платформа с открытым исходным кодом для управления контейнерными рабочими нагрузками и сервисами, которая...
Как создать PHP Image с нуля
Как создать PHP Image с нуля
Сегодня мы создадим PHP Image from Scratch для того, чтобы легко развернуть базовые PHP-приложения. Пожалуйста, имейте в виду, что это разработка для...
1
2
786
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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

Измените IP-адрес в вашем DATABASE_URI на postgres, имя службы в Docker. Обновите его до:

DATABASE_URI=postgres://user:password@postgres:5432/ExperimentOne

Таким образом, Docker обрабатывает IP-адреса внутри себя.

Если вы не уверены в PAYLOAD_SECRET, просто создайте новую случайную строку и замените старую.

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

docker-compose down
docker-compose up -d

И, наконец, убедитесь, что ничто другое на вашем компьютере не использует порт 3000. Если все настроено правильно, вы сможете получить к нему доступ по адресу http://localhost:3000/admin.

Спасибо, я добавил изменение в uri, перезапустил докер, но результат тот же. Я запустил docker-compose logs payload, но вывода не было, и на порту 3000 ничего не работает.

distantStar 06.05.2024 22:42

Бег 5/5; Сетевой эксперимент-one_default Создано; Контейнер эксперимент-один-postgres-1 запущен; Контейнер эксперимент-один-монго-1 запущен; Контейнер эксперимент-один-pgadmin-1 запущен; Контейнер эксперимент-один-полезная нагрузка-1 создан.

distantStar 06.05.2024 22:43

Я добавил больше изображений для отладки. Как видите, журнал пуст.

distantStar 06.05.2024 22:57

Спасибо всем за помощь, но это скорее всего все что мне было нужно, после перезагрузки компьютера все заработало. Возможно, Docker нужно было перезапустить, а не просто запускать docker Compose.

distantStar 07.05.2024 22:00

Несколько вещей:

Но IP-адрес внутри докера не всегда одинаков

Это сделано специально. Обычно вы не хотите использовать частный IP-адрес, который Docker назначает контейнеру, а вместо этого используете имя хоста, которое Docker автоматически создает для мостовых сетей.

Как отметил @Zerx, тогда вы будете ссылаться на свой URI Postgres как postgres://user:password@postgres:5432/ExperimentOne. Где postgres — это имя службы, определенное в вашем файле компоновки.

У вас также отсутствует сетевой блок в вашем файле создания. Сетевой блок должен выглядеть примерно так:

networks:
  myNetwork:
    driver: bridge

Затем в своих сервисах добавьте ключ network для каждого сервиса, к сети которого вы хотите подключиться.

services:
  payload:
    ...
    networks:
      - myNetwork

  postgres:
    ...
    networks:
      - myNetwork

При устранении проблем с сетью необходимо проверить две вещи. Во-первых, после запуска контейнеров проверьте их с помощью docker inspect <container> и посмотрите выходные данные сети. Убедитесь, что все ваши контейнеры находятся в сети с одним и тем же именем. Контейнеры могут принадлежать нескольким сетям, но для того, чтобы два контейнера могли взаимодействовать через мостовую сеть, они оба должны быть ее явной частью.

Во-вторых, установите инструмент nmap внутри вашего сервиса payload (apk add nmap), запустите как postgres, так и контейнеры полезной нагрузки, выполните команду в контейнере полезной нагрузки, а затем проверьте результаты nmap postgres -p 5432. Если nmap сообщает, что порт закрыт или недоступен, значит, сетевое соединение между контейнерами настроено неправильно.

Еще несколько предложений:

  1. Добавьте следующее в свою службу полезной нагрузки, чтобы вам было легче ее использовать.
    stdin_open: true
    tty: true

тогда ты сможешь docker compose exec payload bash

  1. Временно удалите раздел command из определения вашего сервиса. Таким образом, когда вы запускаете службу (после добавления stdin и tty сверху), вы просто получаете работающий альпийский контейнер, в котором вы можете выполнить выполнение. Это позволит вам изолировать проблему сетевого взаимодействия между этим контейнером и службой postgres и какой-либо другой конфигурацией, вызывающей ошибку.

  2. Не пытайтесь повысить все сразу. Начните с одной службы (полезная нагрузка), затем добавляйте остальные по одной (postgres, mongo, pgadmin).

  3. Во время отладки не отключайте драйверы журналирования. Хотя похоже, что ваша база данных postgres запущена и работает, подавляя вывод журнала, вы можете скрыть ошибки.

Блок networks: не нужен; Compose создает сеть с именем default и автоматически присоединяет к ней контейнеры. Я не думаю, что вам нужны и большинство других предложений здесь.

David Maze 06.05.2024 23:58

@DavidMaze Правда — Docker создаст мостовую сеть по умолчанию, но часто это не желаемое поведение. Предпочтительным и более безопасным подходом является четкое указание сетей и их типов, а затем подключение к ним только определенных сервисов (см., например, рекомендации OWASP).

Brian H. 07.05.2024 18:52

Я использую Docker для создания базы данных PostgreSQL.

Вы можете использовать это в сочетании со средой разработки на основе хоста. Если ты бежишь

docker-compose up -d postgres

затем, поскольку служба postgres объявляет ports:, база данных будет доступна с хоста как localhost (при условии, что вы используете Docker Desktop или обычный Docker в собственном Linux) через порт 5432 (первый номер порта).

Затем в вашей хост-среде вы можете запустить

export DATABASE_URI=postgres://user:password@localhost:5432/experimentOne
yarn dev

Отсюда вы используете совершенно обычную среду разработки Node/Yarn, за исключением того, что база данных работает в контейнере.

Эта настройка не использует контейнер payload, и вы можете удалить его. Это просто попытка очень косвенным путем запустить Node в контейнере, но в остальном игнорируя экосистему образов Docker; в большинстве случаев вам будет проще запускать Node напрямую без Docker.

Использование сетевого режима хоста увеличивает поверхность атаки скомпрометированного контейнера, особенно если на сервере выполняются неконтейнерные службы. Для этой настройки нет смысла использовать ее через мостовую сеть.

Brian H. 07.05.2024 18:38

Я думаю, что удаление контейнера, в котором выполняется приложение, и простое размещение человеком вопроса «запускать Node напрямую без Docker» не дает ответа на вопрос и обходит любые проблемы, препятствующие взаимодействию между контейнерами. Существует множество причин, по которым может быть желательно или даже необходимо запускать сервер приложений в Docker. Запуск контейнеров Node в Docker — это обычная установка, которая не игнорирует экосистему образов Docker.

Brian H. 07.05.2024 18:50

Я не призываю использовать здесь хост-сети и согласен, что в целом это плохая идея. Настройка Compose изо всех сил старается избежать создания собственного образа для приложения до такой степени, что переопределение command: повторяется yarn install при каждом запуске, потому что ничто другое этого не делает. Использование инструментов разработки хоста там, где это уместно, может значительно упростить задачу — хотите ли вы docker-compose run payload yarn add ... каждый раз, когда у вас появляется новая зависимость?

David Maze 07.05.2024 19:46

Я пропустил это в файле компоновки. Это хороший момент. Я просто предположил, что в контейнере запущено реальное приложение (поскольку каталог хоста был привязан к контейнеру, что характерно для настроек разработки).

Brian H. 07.05.2024 23:01

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