Swift Vapor 3 PostgreSQL Docker -Составляют правильную конфигурацию?

#postgresql #docker #docker-compose #vapor

#postgresql #docker #docker-составить #vapor

Вопрос:

В настоящее время создается пакет для тестирования некоторых конфигураций DevOps с AWS. Создание приложения с помощью Swift Vapor3, PostgreSQL 11, Docker. Учитывая мое репозиторий на github, проект отлично собирается / тестируется / выполняется с vapor build vapor test vapor run , учитывая, что у вас установлена локальная установка postgresql с username: test, password: test

Однако мой api не подключается к моей базе данных, и я беспокоюсь, что моя конфигурация неправильная.

 version: "3.5"
services:
  api:
    container_name: vapor_it_container
    build:
      context: .
      dockerfile: web.Dockerfile
    image: api:dev
    networks:
      - vapor-it
    environment:
      POSTGRES_PASSWORD: 'test'
      POSTGRES_DB: 'test'
      POSTGRES_USER: 'test'
      POSTGRES_HOST: db
      POSTGRES_PORT: 5432
    ports:
      - 8080:8080
    volumes:
      - .:/app
    working_dir: /app
    stdin_open: true
    tty: true
    entrypoint: bash
    restart: always
    depends_on:
      - db

  db:
    container_name: postgres_container
    image: postgres:11.2-alpine
    restart: unless-stopped
    networks:
      - vapor-it
    ports:
      - 5432:5432
    environment:
      POSTGRES_USER: test
      POSTGRES_PASSWORD: test
      POSTGRES_HOST: db
      POSTGRES_PORT: 5432
      PGDATA: /var/lib/postgresql/data
    volumes:
      - database_data:/var/lib/postgresql/data

  pgadmin:
    container_name: pgadmin_container
    image: dpage/pgadmin4
    environment:
      PGADMIN_DEFAULT_EMAIL: test@test.com
      PGADMIN_DEFAULT_PASSWORD: admin
    volumes:
      - pgadmin:/root/.pgadmin
    ports:
      - "${PGADMIN_PORT:-5050}:80"
    networks:
      - vapor-it
    restart: unless-stopped

networks:
  vapor-it:
    driver: bridge

volumes:
  database_data:
  pgadmin:
  #  driver: local
  

Также, читая документы Docker postgres, я наткнулся на это в разделе «Предостережения».

Если при запуске postgres в контейнере базы данных нет, postgres создаст для вас базу данных по умолчанию. Хотя это ожидаемое поведение postgres, это означает, что он не будет принимать входящие соединения в течение этого времени. Это может вызвать проблемы при использовании средств автоматизации, таких как docker-compose, которые запускают несколько контейнеров одновременно.postgres dockerhub

Я не внес эти изменения, потому что я не уверен, как приступить к созданию этого файла или как будет выглядеть конфигурация. Кто-нибудь делал что-то подобное, у кого есть некоторый опыт подключения к Postgresql и использования vapor в качестве серверной части?

Ответ №1:

Теоретически контейнер с хорошим поведением должен быть способен корректно обрабатывать отсутствие запущенных зависимостей, потому что, несмотря на все усилия вашего планировщика контейнеров, контейнеры могут приходить и уходить. Итак, если вашему приложению нужна база данных, но в любой данный момент база данных недоступна, оно должно реагировать рационально. Например, возвращая значение 503 для HTTP-запроса или повторяя попытку после задержки для запланированной задачи.

Хотя это теория, и она не всегда применима. В вашей ситуации, возможно, вам действительно просто нужно, чтобы ваше приложение Vapor дождалось появления Postgres, и в этом случае вы могли бы использовать скрипт-оболочку, который опрашивает вашу базу данных и запускает ваше основное приложение только после того, как база данных будет готова.

Смотрите этот предлагаемый скрипт-оболочку из документов Docker:

 #!/bin/sh
# wait-for-postgres.sh

set -e

host="$1"
shift
cmd="$@"

until PGPASSWORD=$POSTGRES_PASSWORD psql -h "$host" -U "postgres" -c 'q'; do
  >amp;2 echo "Postgres is unavailable - sleeping"
  sleep 1
done

>amp;2 echo "Postgres is up - executing command"
exec $cmd
  
 command: ["./wait-for-postgres.sh", "db", "vapor-app", "run"]
  

Комментарии:

1. Я читал о том, в какой раздел поместить команду. Находится ли это в службе postgres или в службе api. Я пробовал это на обоих с command: ["./wait-for-postgres.sh","db", "--","swift","run"]

2. Вы бы создали скрипт внутри образа, который также содержит ваш Vapor API, и вы бы установили его в качестве команды / CMD для этого образа. Скрипт просто опрашивает psql до тех пор, пока он не станет доступен, а затем выполняет команду, переданную в качестве аргумента, который должен быть путем к вашему двоичному файлу Vapor и любым аргументам, таким как —hostname .

3. Все, что я когда-либо получаю от вывода моего контейнера api, line 19: psql: command not found независимо от того, как долго он выполняется в контейнере api. тем не менее, контейнер postgres запущен.

4. Это просто означает, что в вашем контейнере API не установлен psql двоичный файл. Я полагаю, что Vapor 3 использует драйвер Postgres на основе Swift, так что раньше он бы вам не понадобился. Попробуйте добавить это на apt-get этапе вашего API Dockerfile.

5. Наверное, мне кажется странным загружать postgresql в мой контейнер api просто для того, чтобы посмотреть, доступен ли он в другом контейнере. Я предполагаю, что теперь проблема заключается в доступе к моему api с localhost, что является совершенно другой проблемой.