Рубрики
Uncategorized

Бег миграции SQL перед загрузкой Docker Compose Services

Хотите больше хорошего контента? Подпишитесь на мою рассылку, посетите: Alec.Coffee/signup Имея G … с меткой Docker, SQL, DEVOPS.

Хотите больше хорошего контента? Зарегистрируйтесь на мою рассылку, посетите: alec.coffee/signup

Наличие отличного местного опыта развития имеет решающее значение для счастливых инженеров. Разработчики рады прийти в кодовую базу и начать взломать проблемы, в отличие от ужасных ноутбуков. Поскольку услуги становятся все более и более разделяющимися на отдельные «микросервисные услуги», возникают новые проблемы. Когда я оглядываюсь на мою короткую карьеру, одна проблема, которая вызвала мне большую боль, — это миграции SQL и как они должны работать в Docker Compose. В идеале они должны работать до загрузки ваших веб-приложений, поэтому у них есть доступ к хорошо структурированной базе данных. Ваша стратегия, чтобы это произошло, может отличаться для каждой среды, в этом посте я покрою ваш локальный опыт, который легко простирается в CI, и я также коснусь, как это сделать в производстве.

Немного фона

Я столкнулся с этой проблемой, когда мы начали принять Федерация Аполлона в наш стек. Один шлюз обслуживает перед нашими другими услугами GraphQL (у которых есть собственные базы данных). Этот шлюз — это то, что клиентские приложения («веб-браузер» на диаграмме) запросы, чтобы получить его данные. Для клиентов начать использование API Gateway, каждая зависимая служба должна быть и здоровой.

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

Типичный Docker Compose файл, который запускает услугу продуктов с ее миграциями, будет выглядеть так:

version: "3.7"

postgres:
  image: yourorg/postgres
  command: postgres -c 'max_connections=1024'
  expose:
    - "5432"
  environment:
    POSTGRES_USER: ${DATABASE_USERNAME}
    POSTGRES_PASSWORD: ${DATABASE_PASSWORD}
  volumes:
    - ${YOUR_ORG_INSTALL_PATH}/volumes/services/postgres-data:/var/lib/postgresql/data:delegated

products-run-migrations:
  build:
    context: ./apps/products/migrations/.
  image: yourorg/products-run-migrations:${IMAGE_TAG:-latest}
  env_file:
    - ./apps/products/products.env
  depends_on:
    - postgres

products:
  build:
    context: ./apps/products/.
  image: yourorg/products:${IMAGE_TAG:-latest}
  env_file:
    - ./apps/products/products.env
  depends_on:
    - postgres
    - products-run-migrations

Несколько вопросов с этой установкой, ориентируясь на Defends_on :

  1. Продукты-пробежные миграции Сценарий будет работать прямо когда Postgres Начинает бегать, а не когда он здоров и готов принять соединения. Есть 99% шанс, что Postgres Контейнер не будет здоров, когда миграции начинают бегать, заставляя их потерпеть неудачу.
  2. Аналогичная ситуация с Продукты Сервис, он будет работать прямо когда Продукты-пробежные миграции начинает бегать. Если вы запрашиваете Продукты Сервис, когда это здорово, есть хороший шанс, что миграции еще не завершены.

Что мы хотим

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

Это требовало меня сделать некоторые исследования.

Я обнаружил, что есть Условия аргумент для зависит от Я мог бы использовать для достижения реализации, которую мы хотели. Но следующая вещь, которую я узнал, — это то, где все прошло хайвире.

Нам нужно было понизить нашу версию Docker-Compose.

Оказывается, Docker Compose 3.x версии предназначены для использования в средах Docker Sharm и Kubernetes, где услуги не строго зависят друг от друга. Это способствует большей неисправной среде, где обслуживания работают независимо.

Что я видел, как люди предлагают должен был переключиться на Docker Compose 2.4 и использовать порт ожидания порта, как ждать-за-это Отказ

Наш новый Docker Compose 2.4 файл:

version: '2.4'

postgres:
  image: yourorg/postgres
  command: postgres -c 'max_connections=1024'
  expose:
    - '5432'
  environment:
    POSTGRES_USER: ${DATABASE_USERNAME}
    POSTGRES_PASSWORD: ${DATABASE_PASSWORD}
  volumes:
    - ${YOUR_ORG_INSTALL_PATH}/volumes/services/postgres-data:/var/lib/postgresql/data:delegated
  healthcheck:
    test: ['CMD-SHELL', 'pg_isready -U root']
    interval: 60s

products-run-migrations:
  build:
    context: ./apps/products/migrations/.
  image: yourorg/products-run-migrations:${IMAGE_TAG:-latest}
  entrypoint:
      - /bin/bash
      - -c
      - 'wait-for-it $$DATABASE_HOSTNAME:5432 -s -t 60 -- npm run db-migrate:products
  restart: on-failure:5
  env_file:
    - ./apps/products/products.env
  depends_on:
      postgres:
        condition: service_healthy

products:
  build:
    context: ./apps/products/.
  image: yourorg/products:${IMAGE_TAG:-latest}
  env_file:
    - ./apps/products/products.env
  restart: on-failure:5
  depends_on:
      postgres:
        condition: service_healthy
      products-run-migrations:
        condition: service_started

Несколько новых дополнений:

  1. Добавил HealthCheck к Postgres контейнер. Это сделало его так, как миграционные сценарии, такие как Продукты-пробежные миграции Можно запустить только тогда, когда база данных готова принять соединения.
  2. Мы добавили Выходная точка вместе с Состояние arg to Defends_on на нашими миграционными изображениями. Это убедилось, что запущена не только база данных, но которую порт возвращает 200 ответов.
  3. Добавлено Состояние Args для обоих Defends_on в Продукты Определение обслуживания.

Это не идеально, но работает намного лучше, чем раньше. Вопрос по-прежнему остается в том, что приложение не ждет миграции, которые будут полностью завершены перед загрузкой. Если они бегут относительно быстро, местные разработчики могут не столкнуться с проблемами. В CI у нас есть полный контроль над окружающей средой, поэтому мы можем добавить дополнительную команду для юбки по этой проблеме.

# .circleci/config.yml
test-products:
  executor: node-docker
  steps:
    - test-project:
        project-name: products
        pre-test-command: docker-compose run -T products-run-migrations
        tests:
          - run-project-test:
              project-name: products

Проблемы, которые все еще остаются

На что я не трогал, это то, какая наша производственная среда выглядит в плане Docker Compose. Мы решили сохранить две версии нашего составных файлов Docker, один в 2,4 и один в 3.7. Это потому, что мы хотим легко принять Кубернаны в будущем. Вы можете придерживаться одного или другого, но для отличного местного опыта развития мы решили всегда иметь 2,4 файла.

Оригинал: «https://dev.to/aleccool213/running-sql-migrations-before-booting-docker-compose-services-3d3d»