Запустите Postgres миграцию с Docker / Docker compose - PullRequest
0 голосов
/ 24 марта 2020

Я довольно новичок во всей этой теме, так что извините, если это глупые вопросы. Я хочу запустить модульные тесты в Docker контейнерах, например, так:

  • Запустить контейнер Postgres без таблиц / данных
  • Запустить миграцию БД (я использую узел -pg-migrate) для создания всех таблиц
  • Заполните БД тестовыми данными
  • Запустите контейнер Node с моей службой
  • Запустите модульные тесты
  • Удалите базу данных
  • Завершите работу / удалите все контейнеры (кроме случаев, когда были ошибки)

В настоящее время я пытаюсь выполнить миграцию. Я создаю сервисный образ FROM моего образа и RUN npm install --only=dev. Мой docker-compose.yml выглядит так:

version: "3.7"
services:
    db:
        image: postgres
        environment: 
            POSTGRES_PASSWORD: test_pw
            POSTGRES_USER: test_user
            POSTGRES_DB: test_db

        ports:
            - '5432:5432'

    web:
        image: docker_tests
        environment:
            DATABASE_URL: postgres://test_user:test_pw@db:5432/test_db?ssl=false
            DATABASE_SSL: "false"
            DATABASE_PW: test_pw
            DATABASE_USER: test_user
            DATABASE_NAME: test_db
            DATABASE_HOST: db
        depends_on: 
            - db
        ports:
            - '1337:1337'

И мой Dockerfile:

FROM docker_service
ENV NODE_ENV TEST
WORKDIR /usr/src/app
RUN npm install --only=dev
RUN ["./node_modules/.bin/node-pg-migrate", "up"]
EXPOSE 1337
CMD ["npm", "run", "test"]

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

No migrations to run!
Migration complete!

Однако, если я запускаю тесты, таблицы недоступны. Миграция не была применена к моему Postgres контейнеру, и при добавлении RUN ["printenv"] после миграции становится понятно, почему: необходимого DATABASE_URL там нет. Я гуглил и обнаружил, что переменные env, указанные в docker-compose.yml, доступны только во время выполнения, а не во время сборки. Однако, когда я добавляю ENV DATABASE_URL ... в свой Dockerfile, он, конечно, не может подключиться к базе данных, так как контейнер Postgres еще не запущен.

Как мне решить проблему? Одним из возможных решений было бы запустить ./node_modules/.bin/node-pg-migrate up в сети, как только оба контейнера будут запущены, но Docker может иметь только одну CMD, верно? И я использую его для запуска своих модульных тестов.

TL; DR: Как запустить миграцию в Docker Postgres -контейнере с использованием node-pg-migrate из Docker service-container до запуска модульных тестов?

Большое спасибо!

1 Ответ

1 голос
/ 24 марта 2020

Я не смог проверить это, но вот идея:

  • содержит скрипт docker-entrypoint.sh в той же папке, что и Dockerfile
#!/usr/bin/env bash

./node_modules/.bin/node-pg-migrate up
exec "$@"
  • измените Dockerfile на использование этого сценария
FROM docker_service
ENV NODE_ENV TEST
WORKDIR /usr/src/app
RUN npm install --only=dev

COPY docker-entrypoint.sh /usr/local/bin/
RUN chmod 777 /usr/local/bin/docker-entrypoint.sh && \
    ln -s usr/local/bin/docker-entrypoint.sh / # backwards compat

ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE 1337
CMD ["npm", "run", "test"]

Таким образом, сценарий docker-entrypoint.sh будет выполняться каждый раз, когда вы создаете контейнер, и впоследствии будет выполняться npm run test из-за exec "$@". Каждый образ БД имеет такую ​​настройку, и я советую вам взглянуть на PostgreSQL Dockerfile и скрипт точки входа .


Возможно, вам понадобится что-то вроде wait-for-it , чтобы убедиться, что БД запущена, перед выполнением сценариев миграции. depends_on помогает вам с порядком запуска, но не ждет, пока служба будет исправна .

Ресурс : Контроль порядок запуска и отключения в Compose

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...