Postgres и Docker повторно развернуть после изменения файла - PullRequest
0 голосов
/ 03 сентября 2018

Я создаю веб-приложение, используя Java / Postgres / Docker / Gradle. Мой проект настроен так:

Существует контейнер БД и контейнер приложения. Контейнер приложения просто запускает простой файл JAR. JAR-файл добавляется с использованием тома из хост-системы. Контейнер изначально запускает этот jar-файл и отслеживает его на предмет изменений. Если он изменяется, он повторно развертывает jar, позволяя разработчикам сразу увидеть изменения на своих локальных машинах. Это похоже на развертывание / обновление файла войны на Tomcat. Живое приложение обновляется, когда вы нажимаете кнопку. Не нужно останавливать приложение, перестраивать и перезапускать: просто перестраивать.

Используя изображение Postgres на Dockerhub, я хочу сделать что-то похожее: я хочу «нажать кнопку» в Gradle, чтобы обновить файл, отслеживаемый контейнером БД, и повторно его развернуть.

К сожалению, я врезался в стену. Моя первоначальная идея состояла в том, чтобы создать Dockerfile, который расширяет Postgres. Все, что нужно сделать, это запустить службу Postgres как обычно и запустить скрипт, который ищет изменения в каком-либо файле и повторно развертывает его.

К сожалению, следующий Dockerfile не работает:

FROM postgres:9.4

WORKDIR /db
COPY monitor.py .
COPY run-pg-and-monitor.sh .

CMD ["run-pg-and-monitor.sh"]

Сценарий оболочки имеет следующие команды:

# Run monitor in the background
python3 monitor.py &

# Run postgres normally
postgres

К сожалению, это не относится к Postgres. Я получаю ошибку:

db_1       | "root" execution of the PostgreSQL server is not permitted.
db_1       | The server must be started under an unprivileged user ID to prevent
db_1       | possible system security compromise.  See the documentation for
db_1       | more information on how to properly start the server.

Если бы мне нужно было задать команду:

CMD ["postgres"]

, что изначально делал контейнер Postgres, ошибка исчезает. Очевидно, это не запускает monitor.py, который мне нужен.

Как ни странно, запуск CMD без квадратных скобок также вызывает эту проблему.

CMD postgres

Запуск из среды оболочки также не выполняется:

CMD ["sh", "-c", "postgres"]

Возможно, это как-то связано с запуском его из оболочки ...

Я знаю, что postgres должен запускаться от пользователя postgres, а не от root. Что я нахожу странным, если установить CMD на:

CMD ["whoami"]

Я получаю:

db_1       | root

Итак, он уже запускал postgres от имени root без проблем.

Вторая идея, которая у меня возникла, заключалась в том, чтобы просто выполнить задание, которое:

1) Обновляет jar, который запускает повторное развертывание для контейнера приложения

2) Запускает docker exec ... для обновления запущенного контейнера БД вручную.

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

У кого-нибудь есть идеи? Есть ли решение, которое уже существует, о котором я не знаю?

1 Ответ

0 голосов
/ 04 сентября 2018

Причиной этих странностей является то, что postgres Dockerfile устанавливает собственный docker-entrypoint.sh сценарий как ENTRYPOINT для изображения. Таким образом, при запуске контейнера docker-entrypoint.sh выполняется, и все, что установлено как CMD, передается сценарию в качестве аргумента (ов).

Сценарий ввода будет выполнять необходимые шаги инициализации для postgres, как удаление привилегий, только если первый переданный аргумент равен postgres (см. здесь и здесь ), прежде чем, наконец, просто выполняя все, что было передано через CMD.

Переопределение ENTRYPOINT вместо CMD, по сути, обертывание docker-entrypoint.sh вашим собственным сценарием, должно дать вам желаемое поведение:

# Run monitor in the background
python3 monitor.py &

# Run postgres normally
docker-entrypoint.sh "$@"
...