Администрирование PostgreSQL, часть 1 - Установка и запуск PostgreSQL в Docker
Приветствую!

Открываю новый цикл статей: будем разбираться в администрировании PostgreSQL с нуля, от установки до репликации, и в первом уроке поднимем сервер в официальном Docker-образе 🐧.

Предисловие

Подобные материалы принято начинать с определения и исторической справки. Будем придерживаться данной традиции.

Что такое СУБД и что такое PostgreSQL

СУБД (система управления базами данных) - программное обеспечение, которое хранит структурированные данные, обеспечивает к ним конкурентный доступ, следит за целостностью и отвечает на запросы через язык SQL. Проще говоря - надёжный посредник между вашими данными и приложениями, которым эти данные нужны.

PostgreSQL - свободная объектно-реляционная СУБД, которую разрабатывает международное открытое сообщество (лицензия PostgreSQL, близкая по духу к MIT/BSD). Среди open-source СУБД она выделяется, пожалуй, самой богатой функциональностью “из коробки” - полноценные транзакции, гибкая система типов, JSON, полнотекстовый поиск, десятки видов индексов и механизм расширений, через который в базу можно добавить практически что угодно, от геоданных (PostGIS) до векторного поиска (pgvector).

Немного истории

История начинается в 1986 году в университете Беркли: Майкл Стоунбрейкер, уже создавший к тому моменту СУБД Ingres, запускает исследовательский проект Postgres - “Post-Ingres”, попытку сделать СУБД с поддержкой пользовательских типов данных и правил. В 1994 году проект обзавёлся собственным интерпретатором SQL и получил имя Postgres95, а в 1996-м, с переходом на открытую модель разработки, был переименован в PostgreSQL - чтобы явно отразить поддержку SQL. С тех пор вышло почти три десятка мажорных версий, а сам проект живёт по предсказуемому годовому циклу релизов.

Вклад российских разработчиков

Отдельно стоит отметить, что в развитии PostgreSQL заметный след оставили и российские разработчики. Олег Бартунов и Фёдор (Теодор) Сигаев из МГУ - авторы инфраструктуры GiST- и GIN-индексов, полнотекстового поиска (tsearch2), типа hstore и ряда других расширений, без которых сложно представить современный PostgreSQL. Александр Коротков - действующий член PostgreSQL Core Team (это высший руководящий орган проекта из считанных человек), внёс значительный вклад в планировщик запросов и индексные методы доступа. А выросшая из той же научной группы компания Postgres Professional - один из крупнейших корпоративных контрибьюторов проекта, поддерживающий собственную сборку Postgres Pro и регулярно отправляющий патчи в апстрим.

PostgreSQL сегодня - это стандартный де-факто выбор и для собственной инфраструктуры, и для облачных сервисов, а администрировать его, рано или поздно приходится любому Linux-админу, даже если в штате есть отдельный DBA. Этот цикл статей призван улучшить взаимопонимание между разными специалистами, чтобы они могли разговаривать на “одном языке”.

Также это способ для меня (и, надеюсь, для вас) узнать/освежить знания о том, как устроен PostgreSQL изнутри, как его настраивать, обслуживать, бэкапить и реплицировать - при этом не забывая и про сам язык SQL, потому что без него администрирование СУБД довольно бессмысленно.

Формат будет такой: каждый урок - отдельная статья, от простого к сложному. Ориентировочно пройдёмся по установке, работе с psql и графическими клиентами, архитектуре и MVCC, конфигурированию, обслуживанию (VACUUM, WAL), хранению данных, системному каталогу, мониторингу, правам доступа, бэкапам и репликации. По ходу дела что-то наверняка добавится или сократится.

Первое отличие от классических курсов: рабочим стендом будет не “живой” PostgreSQL, установленный из пакетов прямо на хост, а официальный образ в Docker. Во-первых, это ближе к тому, как PostgreSQL реально разворачивают в 2026 году. Во-вторых, для учебных целей это просто удобнее: сломали кластер экспериментом - снесли volume и подняли заново за 10 секунд, без переустановки системы.

Примеры данных для практики (таблицы, запросы, домашние задания 😀) будут строиться вокруг вымышленной инфраструктуры - что-то в духе учёта серверов и дата-центров условной хостинг-компании. Базу назвал просто raven. Саму схему таблиц покажу в одном из следующих уроков, когда дойдём до CREATE TABLE.

Структура СУБД PostgreSQL

Вводные данные

ПО, используемое в статье:

ПОВерсия
Debian (хост)13
Docker Engine28
PostgreSQL (образ)18
psql (образ)18
DBeaver Community26

Все команды выполняются на Linux-хосте с уже установленным Docker Engine и плагином docker compose. Дистрибутив хоста непринципиален - контейнер ведёт себя одинаково что на Debian, что на любом другом Linux, в этом и смысл контейнеризации.

Подготовка окружения

Проверяем, что Docker и Compose-плагин на месте:

BASH
sudo docker version

sudo docker compose version
Нажмите, чтобы развернуть и увидеть больше

Создаём директорию проекта:

BASH
sudo install -m 700 -d /etc/compose/postgres
Нажмите, чтобы развернуть и увидеть больше

Выбор образа PostgreSQL

На Docker Hub официальный образ postgres собирается в двух основных вариантах: обычный, на базе Debian, и -alpine, на базе Alpine Linux. Alpine-вариант заметно легче, но использует musl вместо glibc, из-за чего периодически возникают проблемы с локалями и коллациями - а нам ещё предстоит урок про табличные пространства и низкоуровневое хранение, где эти нюансы важны. Поэтому для курса беру обычный образ, без -alpine.

Тег версии - 18, актуальная стабильная ветка PostgreSQL на момент написания статьи. Если к моменту, когда вы это читаете, вышла 19 - в рамках учебного стенда можно смело брать её, принципиальной разницы для наших уроков не будет.

Запуск PostgreSQL в Docker Compose

Создаём compose-файл:

BASH
sudo vim /etc/compose/postgres/compose.yaml
Нажмите, чтобы развернуть и увидеть больше

Наполняем:

YAML
---
# https://hub.docker.com/_/postgres

networks:
  postgres_net:
    name: postgres_net
    driver: bridge
    driver_opts:
      com.docker.network.bridge.name: br-postgres

volumes:
  postgres_data:
    name: postgres_data

services:
  postgres:
    image: postgres:18
    container_name: postgres
    restart: unless-stopped
    stop_grace_period: 1m
    cpus: 2
    mem_limit: 2G
    hostname: postgres
    env_file: ./.env
    networks:
      - postgres_net
    ports:
      - "127.0.0.1:5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 10s
Нажмите, чтобы развернуть и увидеть больше

Порт 5432 публикуем только на 127.0.0.1 - для учебного стенда этого достаточно, а наружу базу лучше не светить без крайней необходимости.

Создаём env-файл:

BASH
sudo vim /etc/compose/postgres/.env
Нажмите, чтобы развернуть и увидеть больше

Наполняем:

INI
# https://hub.docker.com/_/postgres

TZ=Europe/Moscow
POSTGRES_USER=ivan
POSTGRES_PASSWORD=r4ven_me
POSTGRES_DB=raven
PGDATA=/var/lib/postgresql/data/pgdata
Нажмите, чтобы развернуть и увидеть больше

Где:

Запускаем стек:

BASH
sudo docker compose -f /etc/compose/postgres/compose.yaml up -d

sudo docker compose -f /etc/compose/postgres/compose.yaml logs -f
Нажмите, чтобы развернуть и увидеть больше

Проверяем:

BASH
sudo docker compose -f /etc/compose/postgres/compose.yaml ps
Нажмите, чтобы развернуть и увидеть больше

Если всё нормально, увидим примерно такой вывод:

Сразу же настроим автозапуск и управление нашей СУБД с помощью Systemd:

BASH
sudo tee /etc/compose/postgres/postgres.service << EOF
[Unit]
Description=PostgreSQL course lab service
Requires=docker.service
After=docker.service

[Service]
Restart=always
RestartSec=5
User=root
Group=root
WorkingDirectory=/etc/compose/postgres
ExecStart=/usr/bin/docker compose up --remove-orphans
ExecStop=/usr/bin/docker compose down

[Install]
WantedBy=multi-user.target
EOF
Нажмите, чтобы развернуть и увидеть больше
BASH
sudo chmod 600 /etc/compose/postgres/postgres.service

sudo ln -vs /etc/compose/postgres/postgres.service /etc/systemd/system

sudo systemctl daemon-reload

sudo systemctl enable --now postgres

sudo systemctl status postgres
Нажмите, чтобы развернуть и увидеть больше

Теперь сервисом postgres можно управлять утилитой systemctl, а журнал сервиса с помощью journalctl:

BASH
sudo systemctl stop postgres
sudo systemctl start postgres
sudo systemctl restart postgres
sudo systemctl status postgres
sudo journalctl -fu postgres
Нажмите, чтобы развернуть и увидеть больше

Проверка подключения

Смотреть на СУБД можно двумя способами - через консольный psql и через графический клиент. В следующем уроке разберём оба инструмента подробно, а пока просто убедимся, что сервер живой и отвечает.

Через psql

psql уже есть внутри образа, отдельно ставить ничего не нужно - выполняем его прямо в контейнере:

BASH
sudo docker compose -f /etc/compose/postgres/compose.yaml exec postgres psql -U ivan -d raven -c "SELECT version();"
Нажмите, чтобы развернуть и увидеть больше

Если всё нормально, увидим примерно такой вывод:

Через DBeaver

В качестве графического клиента в этом курсе буду использовать DBeaver Community - он открытый, бесплатный, кроссплатформенный и умеет практически всё, что нужно для администрирования PostgreSQL. Скачиваем нужную версию, устанавливаем и запускаем.

Далее создаём новое подключение к нашей БД (New Database ConnectionPostgreSQL), указав следующие параметры:

Проверяем подключение кнопкой Test Connection...:

Затем открываем SQL-редактор и выполняем тот же запрос, что и в psql:

SQL
SELECT version();
SELECT current_date;
Нажмите, чтобы развернуть и увидеть больше

Отлично! Сервер поднят, доступен и из консоли, и из GUI - можно двигаться дальше.

Сброс окружения для экспериментов

Отдельно стоит сказать про то, как быстро вернуть стенд в чистое состояние - за курс наверняка захочется не раз всё сломать намеренно и начать заново:

BASH
sudo systemctl stop postgres

sudo systemctl disable postgres

sudo docker image rm postgres:18

sudo docker volume rm postgres_data

sudo docker network rm postgres_net

sudo rm -rf /etc/compose/postgres
Нажмите, чтобы развернуть и увидеть больше

Возможные проблемы

TXT
Error response from daemon: driver failed programming external connectivity on endpoint postgres: Bind for 127.0.0.1:5432 failed: port is already allocated
Нажмите, чтобы развернуть и увидеть больше

Чаще всего это значит, что на хосте уже крутится “живой” PostgreSQL, установленный из пакетов. Либо остановите его, либо смените порт публикации в compose.yaml, например на 127.0.0.1:5433:5432 (не забудьте поменять порт и в подключении DBeaver).

Если вы меняли POSTGRES_PASSWORD в .env уже после первого запуска - это ожидаемо, см. предупреждение выше про инициализацию кластера. Проще всего либо поменять пароль изнутри (ALTER ROLE ivan WITH PASSWORD '...'), либо, если данные ещё не жалко, пересоздать volume.

Послесловие

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

В следующем уроке подробно разберём утилиту psql, а заодно освоимся в графический клиент DBeaver уже более предметно.

В качестве внеклассной работы рекомендую посмотреть очень интересное интервью с Иваном Панченко, сооснователем компании Postgres Pro. В видео речь идёт об идеологии open source, вкладе наших соотечественников в развитие проекта Postgres, сравнение с Oracle и многое другое. Очень интересно следить за ходом мыслей Ивана, в плане использования модели открытого ПО для бизнеса. Ну и конечно же интересно слушать про различные нюансы этой модели, а также про историю развития СУБД.

В общем рекомендую 👍.

Длительность видео больше полутора часа, но смотрится на одном дыхании 😌.

Спасибо, что читаете. Успехов в изучении PostgreSQL! 🐧

Используемые материалы

Комментарии

Авторские права

Автор: Иван Чёрный

Ссылка: https://r4ven.me/storage/administrirovanie-postgresql-chast-1-ustanovka-i-zapusk-postgresql-v-docker/

Лицензия: CC BY-NC-SA 4.0

Использование материалов блога разрешается при условии: указания авторства/источника, некоммерческого использования и сохранения лицензии.

Начать поиск

Введите ключевые слова для поиска статей

↑↓
ESC
⌘K Горячая клавиша