Sign inSign up

grufos/postgres

By grufos

Updated over 2 years ago

Image
0

2.6K

grufos/postgres repository overview

docker-postgres

Оригинальный код: https://github.com/sgrinko/docker-postgres

Докер основан на официальном образе postgres и postgis:

https://hub.docker.com/_/postgres
https://github.com/docker-library/postgres

https://hub.docker.com/r/postgis/postgis
https://github.com/postgis/docker-postgis

Контейнер ориентирован на работу с русской локалью. Внутри выполняются следующие команды для локализации:

RUN localedef -i ru_RU -c -f UTF-8 -A /usr/share/locale/locale.alias ru_RU.UTF-8
ENV LANG ru_RU.utf8

Инициализация новой БД выполняется по умолчанию с параметрами к initdb: --locale=ru_RU.UTF8 --data-checksums

Дополнительно добавлены следующие компоненты:

  • pg_probackup - утилита для работы с бэкапами от Postgres Professional
  • sendemail - используется для отправки почты
  • установлен пакет для коннекта к MSSQL через FDW расширение tds_fdw c использованием пакета freetds. В файле конфигурации /etc/freetds/freetds.conf для параметра text size установлено значение: 1262485504 (1204Мб)
  • В БД postgres добавлено расширение pg_cron для возможности выполнения заданий внутри каждой БД по расписанию. В других БД создаётся обертка из схемы pg_cron, 2-х внешних таблиц и нескольких функций, что позволяет использовать простое управление заданиями локально для каждой БД.
  • htop - удобная утилита для просмотра запущенных процессов внутри контейнера
  • mc - всем известный файловый менеджер
  • дополнительно к исходным 3-м БД создана шаблонная БД с именем template_extension

В шаблонную БД установлены расширения:

ExtensionDescription
adminpackadministrative functions for PostgreSQL
amcheckfunctions for verifying relation integrity
btree_ginsupport for indexing common datatypes in GIN
citextdata type for case-insensitive character strings
dblinkconnect to other PostgreSQL databases from within a database
file_fdwforeign-data wrapper for flat file access
fuzzystrmatchdetermine similarities and distance between strings
hunspell_en_usen_US Hunspell Dictionary
hunspell_ru_ruRussian Hunspell Dictionary
hunspell_ru_ru_aotRussian Hunspell Dictionary (from AOT.ru group)
pageinspectinspect the contents of database pages at a low level
pg_buffercacheexamine the shared buffer cache
pg_dbo_timestampPostgreSQL extension for storing time and author of database structure modification
pg_prewarmprewarm relation data
pg_repackReorganize tables in PostgreSQL databases with minimal locks
pg_stat_statementstrack execution statistics of all SQL statements executed
pg_trgmtext similarity measurement and index searching based on trigrams
pg_tsparserparser for text search
pg_variablessession variables with various types
pgstattupleshow tuple-level statistics
pldbgapiserver-side support for debugging PL/pgSQL functions
plpgsqlPL/pgSQL procedural language
plpgsql_checkextended check for plpgsql functions
plpython3uPL/Python3U untrusted procedural language
postgisPostGIS geometry, geography, and raster spatial types and functions
postgis_tiger_geocoderPostGIS tiger geocoder and reverse geocoder
postgis_topologyPostGIS topology spatial types and functions
postgres_fdwforeign-data wrapper for remote PostgreSQL servers
rumRUM index access method
shared_ispellProvides shared ispell dictionaries.
uuid-osspgenerate universally unique identifiers (UUIDs)

Настроены 5 конфигураций полнотекстового поиска для русского и английского языка:

NameDescription
fts_aot_en_ruFTS hunspell AOT configuration for russian language based on shared_ispell without stopwords
fts_aot_en_ru_swFTS hunspell AOT configuration for russian language based on shared_ispell with stopwords
fts_hunspell_en_ruFTS hunspell Lebedev configuration for russian language based on shared_ispell without stopwords
fts_hunspell_en_ru_swFTS hunspell Lebedev configuration for russian language based on shared_ispell with stopwords
fts_snowball_en_ru_swFTS snowball configuration for russian language based on tsparser with stopwords

Особенность:

  • использование парсера tsparser и загрузки используемых словарей в общую память однократно при старте сервера. Используется расширение shared_ispell. Русские и английские словари взяты из расширения hunspell_dicts
  • 3 конфигурации с использованием стоп-слов (постфикс "_sw") и 2 конфигурации без использования стоп-слов

Старт контейнера

Контейнер рассчитан на 2 режима начального старта:

  • Старт с пустым каталогом данных

При запуске контейнера с пустым каталогом данных выполняется его инициализация через вызов initdb и созданием шаблонной БД template_extension. Из-за особенностей старта официального образа при такой инициализации не выполняется создание расширений pg_cron и ispell_shared, а также не выполняется настройка конфигураций полнотекстового поиска. Поэтому после такого первого старта очень желательно выполнить запуск скрипта обновления БД кластера через команду:

$ docker exec -it temp_postgres_1 update-extension.sh <доп.БД>

где имя temp_postgres_1 - имя запущенного postgres-контейнера. В выводе команды docker ps это колонка NAMES.

<доп.БД> - можно передать имя пользовательской БД которую необходимо "дотянуть" до стандарта по расширениям и настройкам текущего контейнера. БД должна быть уже создана.

Если же в настройках docker-compose файла указать:

command: |
      -c shared_preload_libraries='plugin_debugger,pg_stat_statements,auto_explain,pg_buffercache,pg_cron,shared_ispell,pg_prewarm'
      -c shared_ispell.max_size=70MB

то проблему 1-го старта с последующей донастройкой можно избежать. Однако надо помнить, что указание такой строки в качестве параметра старта службы не позволит изменить эти значение через файл настроек.

  • Старт с уже инициализированным каталогом

Когда контейнер запускается с уже присоединённым каталогом кластера БД, то никаких внутренних скриптов инициализации не применяется. Однако, если есть желание "дотянуть" до стандарта по расширениям и настройкам текущего контейнера, то необходимо иметь ввиду, что для полноценной работы внутренних скриптов необходимо в настройках кластера загружать следующие shared библиотеки:

shared_preload_libraries='plugin_debugger,pg_stat_statements,auto_explain,pg_buffercache,pg_cron,shared_ispell,pg_prewarm'

а также в файле настроек указать параметр:

shared_ispell.max_size=70MB

Чтобы "дотянуть" БД до стандарта по расширениям и настройкам текущего контейнера выполните вызов скрипта: update-extension.sh как описано чуть выше.

В кластере БД, созданном с нуля, pg_hba.conf и pg_ident.conf имеют значения, рассчитанные на вход по паролю (на это оказывает влияние параметр POSTGRES_HOST_AUTH_METHOD), а postgresql.conf оптимизирован под 2 ГБ ОЗУ и SSD диски. При необходимости, после первичной инициализации уточните параметры конфигурации.

Пользовательская БД

Чтобы создать свою БД, рекомендуется использовать шаблон template_extension:

CREATE DATABASE my_db WITH TEMPLATE template_extension;

В созданной таким образом БД настроены все необходимые расширения и создана схема с именем dbo как схема для пользовательских таблиц. Однако права и пути поиска нельзя перенести таким образом, поэтому для дотягивания БД до стандартов контейнера нужно выполнить скрипт: update-extension.sh как описано чуть выше и передать как параметр этому скрипту имя созданной БД.

$ docker exec -it temp_postgres_1 update-extension.sh my_db

Путь поиска после выполнения скрипта в указанной БД выглядит так: search_path = dbo, public, tiger;

Работа с бэкапами

Контейнер рассчитан на работу с утилитой бэкапирования pg_probackup от компании Postgres Professional. В настройках archive_command и restore_command написана bash команда для вызова архивации/восстановления WAL файлов:

archive_command:
if [ -f archive_pause.trigger ]; then exit 1; else if [ -f archive_active.trigger ]; then pg_probackup-13 archive-push -B /mnt/pgbak --instance 13 --wal-file-path %p --wal-file-name %f -j 4 --batch-size=50; else exit 0; fi; fi

restore_command:
if [ -f archive_active.trigger ]; then pg_probackup-13 archive-get -B /mnt/pgbak --instance 13 --wal-file-path %p --wal-file-name %f; else exit 0; fi

Чтобы WAL файлы начали сохраняться, нужно в каталоге данных создать файл с именем: archive_active.trigger (автоматически создаётся при первом вызове backup.sh) При его наличии каждый WAL файл сохраняется в бэкап-каталог.

При его отсутствии WAL файлы не сохраняются!

Чтобы временно приостановить выгрузку WAL файлов в бэкап-каталог нужно создать файл: archive_pause.trigger (это может понадобиться для временных работ с бэкапным каталогом).

В контейнере есть 3 дополнительных скрипта:

backup.sh - создаёт новый бэкап

show.sh - показывает какие бэкапы есть

check_cluster.sh - выполняет проверку кластера на возможные ошибки в структуре БД

Для запуска можно использовать команды:

$ docker exec -it temp_postgres_1 backup.sh
$ docker exec -it temp_postgres_1 show.sh
$ docker exec -it temp_postgres_1 check_cluster.sh

Скрипт backup.sh может принимать до 3-х параметров:

$1 - количество потоков для выполнения бэкапа: 4 (по умолчанию) или указанное число
$2 - указывает режим создания инкрементального бэкапа: delta (по умолчанию) или page
$3 - признак создания автономного бэкапа типа stream: yes (по умолчанию) или любой другой текст для варианта "archive"

Скрипт show.sh может принимать до 2-х параметров:

$1 - yes/no (нужно ли отсылать письмо с отчетом по текущим бэкапам)
$2 - список email получателей письма (через пробел и обрамить двойными кавычками)

Скрипт check_cluster.sh может принимать до 2 -х параметров:

$1 - 'amcheck' включить доп.проверку кластера при помощи расширения amcheck
$2 - 'heapallindexed' будет дополнительно проверено, что в индексе действительно представлены все кортежи кучи, которые должны в него попасть

Переменные окружения контейнера

Часть переменных имеет значения по умолчанию, это значит, что если их не указывать при старте контейнера, то они имеют указанные значения.

Переменные использующиеся только при первичной инициализации:

NameDefault valueDescription
POSTGRES_INITDB_ARGS--locale=ru_RU.UTF8 --data-checksumsЭту необязательную переменную среды можно использовать для отправки аргументов в postgres initdb. Значение представляет собой строку аргументов, разделенных пробелами, как того и ожидает postgres initdb.
POSTGRES_HOST_AUTH_METHODmd5Эту необязательную переменную можно использовать для управления методом аутентификации для соединений с хостом для всех баз данных, всех пользователей и всех адресов. Это значение используется только на этапе первичной инициализации.
PGDATA/var/lib/postgresql/dataЭту необязательную переменную можно использовать для определения другого местоположения - например, подкаталога - для файлов базы данных. По умолчанию это /var/lib/postgresql/data. Если используемый вами том данных является точкой монтирования файловой системы (например, с постоянными дисками GCE) или удаленной папкой, которая не может быть подключена для пользователя postgres (например, некоторые точки монтирования в NFS), Postgres initdb рекомендует создать подкаталог для хранения данных
POSTGRES_INITDB_WALDIRPGDATA/pg_walЭту необязательную переменную среды можно использовать для определения другого места для журнала транзакций Postgres. Иногда может быть желательно хранить журнал транзакций в другом каталоге, который может поддерживаться хранилищем с другими характеристиками производительности или надежности.

Пример показывающий использование подкаталога для каталога данных:

$ docker run -d \
    --name some-postgres \
    -e POSTGRES_PASSWORD=qweasdzxc \
    -e PGDATA=/var/lib/postgresql/data/pgdata \
    -v /custom/mount:/var/lib/postgresql/data \
    postgres

Обратите внимание, что мы подключаемый каталог монтируем на 1 уровень выше, чем указали в переменной PGDATA. В этом и есть смысл использования переменной PGDATA

Переменные с данными по подключению к БД:

NameDefault valueDescription
POSTGRES_USERpostgresЭта переменная создаст указанного пользователя с полномочиями суперпользователя и базу данных с тем же именем. Не рекомендуется менять значение этой переменной.
POSTGRES_DBpostgresЭту необязательную переменную среды можно использовать для определения другого имени для базы данных по умолчанию, которая создается при первом запуске образа. Если он не указан, будет использоваться значение POSTGRES_USER. Не рекомендуется менять значение этой переменной.
POSTGRES_PASSWORDОпределяет пароль пользователя POSTGRES_USER. Это значение указывается в настройках мапинга пользователя для FDW серверов.
DEV_SCHEMAdboИмя схемы, выбираемая как схема по умолчанию для пользовательских объектов. Это имя включается в параметр search_path и эта схема создается если её нет.
DEPLOY_PASSWORDПароль для создаваемого пользователя с именем deploy. Это пользователь с повышенными правами, но не superuser. Предполагается, что он будет владельцем всех создаваемх БД и объектов в них

Переменная указывающая на временную зону в которой работает контейнер:

NameDefault valueDescription
TZУказывает на временную зону в которой работает контейнер. Например: "Europe/Moscow" или "Etc/UTC"

Переменные для отправки писем:

NameDefault valueDescription
EMAILTOНа какой адрес отправлять почтовые сообщения
EMAIL_SERVERИмя почтового сервера для отправки писем
EMAIL_HOSTNAMEnoreply@my_host.ruимя отправителя писем
EMAIL_SENDyesОтправку писем можно отменить указав no

Переменные влияющие на работу скриптов по бэкапам:

NameDefault valueDescription
BACKUP_MODEdeltaРежим инкрементального бэкапа. Альтернативное значение page
BACKUP_PATH/mnt/pgbakКаталог используемый утилитой pg_probackup для хранения всех бэкапов
BACKUP_THREADS4На сколько потоков можно параллелить бэкап/рестор процесс
BACKUP_STREAMyesyes - создавать автономные резервные копии. no - создавать резервные копии для которых обязательно нужны WAL файлы.

Предустановленные роли

Контейнер поддерживает следующие предустановленные роли (используйте скрипт update-extension.sh)

рольописаниепараметры
mamonsuспециализированная роль для активного агента mamonsuLOGIN NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION
deployроль владелец для всех новых БД и их объектовLOGIN NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION PASSWORD
replicatorроль для использования с логической и потоковой репликациейLOGIN NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION
readonly_groupроль-группа выдающая права на чтение таблиц, использование последовательностей и типовNOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION
write_groupроль-группа выдающая права на чтение/запись таблиц, последовательностей и использование типовNOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION
execution_groupроль-группа выдающая права на запуск всех функций и процедурNOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION

Каталоги для маппинга

Контейнер ожидает следующие примапленные каталоги

NameDescription
/var/lib/postgresql/dataкаталог с данными кластера
/var/log/postgresqlкаталог с файлами логов
/mnt/pgbakкаталог для бэкапов кластера
/usr/share/postgresql/tsearch_dataкаталог хранения словарей для FTS

Обратите внимание, что на подключаемые каталоги нужно заранее выдать права на запись пользователю с uid=999 (код пользователя postgres внутри контейнера)

Пример старта контейнера через docker run

запуск без примапленных каталогов. Всё данные кластера будут храниться внутри докер контейнера. В данном примере postgres мапится на порт 5433.

docker run -d --name dev-db -p 5433:5432/tcp --shm-size 2147483648 \
           -e POSTGRES_PASSWORD=qweasdzxc \
           -e POSTGRES_HOST_AUTH_METHOD=trust \
           -e DEPLOY_PASSWORD=cxzdsaewq \
           -e TZ="Etc/UTC" \
           grufos/postgres:13.3 \
           -c shared_preload_libraries="plugin_debugger,pg_stat_statements,auto_explain,pg_buffercache,pg_cron,shared_ispell,pg_prewarm" \
           -c shared_ispell.max_size=70MB

запуск с указанием примапленных каталогов. Все данные кластера будут храниться вне контейнера в каталоге /var/lib/pgsql/13/data, а логи в каталоге /var/log/postgresql

docker run -d --name dev-db -p 5433:5432/tcp --shm-size 2147483648 \
       -e POSTGRES_PASSWORD=qweasdzxc \
       -e POSTGRES_HOST_AUTH_METHOD=trust \
       -e DEPLOY_PASSWORD=cxzdsaewq \
       -e TZ="Etc/UTC" \
       -v "/var/lib/pgsql/13/data:/var/lib/postgresql/data" \
       -v "/var/log/postgresql:/var/log/postgresql" \
       -v "/mnt/pgbak2:/mnt/pgbak" \
       -v "/usr/share/postgres/tsearch_data:/usr/share/postgresql/tsearch_data" \
       grufos/postgres:13.3 \
       -c shared_preload_libraries="plugin_debugger,pg_stat_statements,auto_explain,pg_buffercache,pg_cron,shared_ispell,pg_prewarm" \
       -c shared_ispell.max_size=70MB

остановка контейнера

docker stop dev-db

запуск ранее остановленного контейнера

docker start dev-db

Пример docker-compose файла

Создаём файл postgres-service.yml

version: '3.5'
services:
 
  postgres:

#    image: grufos/postgres:13.3
    build:
      context: ./docker-postgres
      dockerfile: Dockerfile
    shm_size: '2gb'
    command: |
      -c shared_preload_libraries='plugin_debugger,pg_stat_statements,auto_explain,pg_buffercache,pg_cron,shared_ispell,pg_prewarm'
      -c shared_ispell.max_size=70MB
    volumes:
      - "/var/lib/pgsql/13_1/data:/var/lib/postgresql/data"
      - "/var/log/postgresql1:/var/log/postgresql"
      - "/mnt/pgbak2/:/mnt/pgba

Tag summary

Content type

Image

Digest

sha256:cf26a463c

Size

244.5 MB

Last updated

over 2 years ago

docker pull grufos/postgres