Как дождаться готовности Postgres перед загрузкой данных в Docker Compose - PullRequest
0 голосов
/ 18 июня 2020

У меня есть простой Docker Файл:

version: "3"

volumes:
    pg-data:

services:
    db:
        image: postgis/postgis
        build: ./postgis

        volumes: 
            - pg-data:/var/lib/postgresql

        ports: 
            - 5432:5432

        restart: on-failure

Мой Dockerfile:

FROM postgis/postgis

USER root

COPY docker-entrypoint.sh /docker-entrypoint.sh
COPY data_load.sh /data_load.sh
RUN chmod +x /*.sh

ENTRYPOINT ["/docker-entrypoint.sh"]

Мой docker-entrypoint.sh:

exec /data_load.sh &
exec /docker-entrypoint.sh

Мой data_load.sh:

until pg_isready -h localhost -p 5432
do
    printf 'PostgreSQL not ready! \n'
    sleep 15
done

echo "Loading data"
python /load_data.py &&
echo "Data load complete!"

При запуске docker-compose up --build получаю:

...
Successfully built 88b291d6b47e
Successfully tagged postgis/postgis:latest
Creating my_compose_db_1 ... done
Attaching to my_compose_db_1
db_1  | Starting script to add data
db_1  | localhost:5432 - no response
db_1  | PostgreSQL not ready yet, trying again in 15 seconds 

Проблема в том, что Postgres никогда не запускается! Скрипт data_load. sh выполняется, поскольку я вижу, что «PostgreSQL не готов!» распечатывается каждые 15 секунд. Идеи о том, что я делаю не так?

1 Ответ

0 голосов
/ 18 июня 2020

В имеющейся у вас настройке скрипта ничто никогда не запускает точку входа базового образа. Вы предоставляете свой собственный сценарий как /docker-entrypoint.sh, который завершается повторным запуском. (Базовое изображение postgres помещает свой сценарий точки входа в /usr/local/bin/docker-entrypoint.sh.)

Для производного изображения PostgreSQL будет работать гораздо более простая установка. При первой инициализации стандартный образ postgres будет запускать любые сценарии *.sql или *.sh в /docker-entrypoint-initdb.d, и вам гарантируется, что база данных работает в этой конкретной точке. Поэтому, если вы уменьшите размер сценария загрузчика до

#!/bin/sh
exec /load_data.py

и скопируете его в правильный каталог

FROM postgis/postgis
COPY data_load.sh /docker-entrypoint-initdb.d/data_load.sh
COPY load_data.py /load_data.py
RUN chmod +x /docker-entrypoint-initdb.d/data_load.sh /load_data.py
# And use the base image's ENTRYPOINT/CMD

, вам вообще не нужно писать этот сценарий вручную.

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

...