Не удается создать расширение pg_cron в docker-entrypoint-initdb.d
Если я создаю расширение pg_cron в docker-entrypoint-initdb.d/init.sql
файл, образ докера не запускается и docker logs <id>
просто говорит "Нет такого контейнера". Вот соответствующий фрагмент.sql:
CREATE DATABASE my_database;
\c my_database;
CREATE EXTENSION IF NOT EXISTS postgis CASCADE;
CREATE EXTENSION IF NOT EXISTS timescaledb CASCADE;
CREATE EXTENSION IF NOT EXISTS pg_cron CASCADE;
Тем не менее, если я создаю расширение pg_cron после завершения команды docker run (т.е. удалите последнюю строку выше и запустите ее отдельно с psql --file
после docker run
завершается), расширение создается успешно (расширения postgis и timescaledb кажутся нормальными независимо).
Есть ли причина, по которой я не могу создать расширение pg_cron из docker-entrypoint-init.d
? Есть ли правильное место?
Моя команда запуска Docker выглядит следующим образом:
docker run -d \
--name my_container --rm \
-p 5432:5432 \
-clog_line_prefix="%m [%p]: [%l-1] %u@%d" \
-clog_error_verbosity=VERBOSE \
-cshared_preload_libraries='timescaledb,pg_cron' \
-ccron.database_name='my_database'
3 ответа
pg_cron
может быть загружен только как общая библиотека. Вы должны указать это в postgres.conf
файл. Поскольку все сценарии в docker-entrypoint-init.d
выполняются после запуска сервера postgres (с pg_ctl start
), все изменения shared_preload_libraries
в postgres.conf
может стать доступным после перезапуска (с pg_ctl restart
).
Пример из реального мира:
002-setup.sh:
#!/bin/sh
# Remove last line "shared_preload_libraries='citus'"
sed -i '$ d' ${PGDATA}/postgresql.conf
cat <<EOT >> ${PGDATA}/postgresql.conf
shared_preload_libraries='pg_cron,citus'
cron.database_name='${POSTGRES_DB:-postgres}'
EOT
# Required to load pg_cron
pg_ctl restart
003-main.sql:
CREATE EXTENSION pg_cron;
Обратите внимание:
- порядок выполнения скрипта имеет значение и упорядочен по именам файлов
pg_cron
становится доступным в БД, указанном сcron.database_name
Предлагаемое решение не сработало для меня с вновь созданным контейнером. Итак, я сделал это так:
Файл Docker
FROM postgres:13.2
RUN apt-get update && apt-get -y install git build-essential postgresql-server-dev-13
RUN git clone https://github.com/citusdata/pg_cron.git
RUN cd pg_cron && make && make install
RUN cd / && \
rm -rf /pg_cron && \
apt-get remove -y git build-essential postgresql-server-dev-13 && \
apt-get autoremove --purge -y && \
apt-get clean && \
apt-get purge
COPY init-db /docker-entrypoint-initdb.d
init-db / 002-pg-cron.sh
#!/usr/bin/env bash
# use same db as the one from env
dbname="$POSTGRES_DB"
# create custom config
customconf=/var/lib/postgresql/data/custom-conf.conf
echo "" > $customconf
echo "shared_preload_libraries = 'pg_cron'" >> $customconf
echo "cron.database_name = '$dbname'" >> $customconf
chown postgres $customconf
chgrp postgres $customconf
# include custom config from main config
conf=/var/lib/postgresql/data/postgresql.conf
found=$(grep "include = '$customconf'" $conf)
if [ -z "$found" ]; then
echo "include = '$customconf'" >> $conf
fi
Кроме того, вы можете поместить другие файлы инициализации в каталог init-db.
003-main.sql
CREATE EXTENSION pg_cron;
Docker создать файл
version: '3.7'
services:
postgres:
container_name: your-container
build: .
environment:
POSTGRES_DB: "your_db"
POSTGRES_USER: "your_user"
POSTGRES_PASSWORD: "your_user"
volumes:
- pgdata:/var/lib/postgresql/data
ports:
- "5432:5432"
volumes:
pgdata:
driver: local
Вам необходимо установить и настроить
pg_cron
расширение.
Я рекомендую вам использовать (или хотя бы разветвить) этот репозиторий: ramazanpolat / postgres_cron: Dockerfile для сборки postgresql:11 с расширением pg_cron