В этом руководстве мы научимся устанавливать PostgreSQL с помощью Docker. Обычно мы запускаем контейнер Docker, используя публичный образ Docker, или берём предварительно настроенные Docker-образы сервера баз данных PostgreSQL из Docker Hub. Здесь же мы продемонстрируем, как PostgreSQL можно установить, настроить и запустить на Docker.

Сначала запустим контейнер Docker с базой данных PostgreSQL, используя публичный образ PostgreSQL. Позже мы создадим пользовательский Dockerfile для установки сервера PostgreSQL в контейнер Docker. Также мы научимся создавать резервные копии и восстанавливать базу данных с помощью контейнера Docker.

Оглавление:


  1. Знакомство с базой данных PostgreSQL
  2. Установка PostgreSQL с помощью публичного образа
  3. Установка PostgreSQL с помощью пользовательского Dockerfile
  4. Установка pgAdmin на Docker
  5. Резервное копирование и восстановление данных

Давайте подробно рассмотрим запуск Docker-контейнера с базой данных PostgreSQL.

1. Знакомство с базой данных PostgreSQL


Прежде чем мы перейдём к запуску Docker-контейнера базы данных PostgreSQL, давайте сначала разберёмся, что она вообще из себя представляет.
PostgreSQL — это СУБД с открытым исходным кодом, аналогичная MySQL. Это объектно-ориентированная база данных, но с её помощью мы можем обрабатывать как структурированные, так и неструктурированные данные.
Механизм базы данных PostgreSQL работает на различных платформах, включая Windows, Mac OS X и Linux. Он также предоставляет расширенные типы данных и функции оптимизации производительности для хранения и масштабирования сложных рабочих нагрузок БД.

2. Установка PostgreSQL с помощью публичного образа


Чтобы запустить PostgreSQL с помощью Docker, нам сначала нужно извлечь публичный образ postgres, доступный на Docker Hub:

$ docker pull postgres
Using default tag: latest
latest: Pulling from library/postgres
1fe172e4850f: Pull complete
...
c08147da7b54: Pull complete
Digest: sha256:ab0be6280ada8549f45e6662ab4f00b7f601886fcd55c5976565d4636d87c8b2
Status: Downloaded newer image for postgres:latest
docker.io/library/postgres:latest

В приведённой выше команде мы вытянули последний стабильный образ postgres. Мы также можем использовать определённую версию образа postgres с помощью следующей команды:

$ docker pull postgres:14.2
14.2: Pulling from library/postgres
Digest: sha256:e3d8179786b8f16d066b313f381484a92efb175d1ce8355dc180fee1d5fa70ec
Status: Downloaded newer image for postgres:14.2
docker.io/library/postgres:14.2

Теперь запустим контейнер Docker, используя образ postgres:latest:

$ docker run -itd -e POSTGRES_USER=baeldung -e POSTGRES_PASSWORD=baeldung -p 5432:5432 -v
/data:/var/lib/postgresql/data --name postgresql postgres
5aeda2b20a708296d22db4451d0ca57e8d23acbfe337be0dc9b526a33b302cf5

Данная команда использует переменные среды POSTGRES_USER и POSTGRES_PASSWORD для установки имени пользователя и пароля для БД PostgreSQL. Также база данных PostgreSQL по умолчанию должна работать на порте 5432, и мы открыли его на хосте, используя переменную "-p 5432:5432" в команде docker run.

Для резервного копирования данных мы также смонтировали каталог /var/lib/postgresql/data в каталог /data на хост-машине контейнера postgres.

psql — это утилита командной строки, используемая для интерактивного доступа к БД PostgreSQL. Давайте воспользуемся psql для соединения с базой данных:

$ PGPASSWORD=baeldung psql -U baeldung

Чтобы получить список всех баз данных, воспользуемся командой \l:

$ PGPASSWORD=baeldung psql -U baeldung -c '\l'
                                    List of databases
    Name    |   Owner    | Encoding |  Collate   |   Ctype    |     Access privileges     
------------+------------+----------+------------+------------+---------------------------
 baeldung   | baeldung   | UTF8     | en_US.utf8 | en_US.utf8 |
 postgres   | baeldung   | UTF8     | en_US.utf8 | en_US.utf8 |
 template0  | baeldung   | UTF8     | en_US.utf8 | en_US.utf8 | =c/baeldung            +
            |            |          |            |            | baeldung=CTc/baeldung
 template1  | baeldung   | UTF8     | en_US.utf8 | en_US.utf8 | =c/baeldung            +
            |            |          |            |            | baeldung=CTc/baeldung
(4 rows)

В показанном выше выводе мы можем увидеть подробную информацию обо всех базах данных, имеющихся на сервере PostgreSQL.

3. Установка PostgreSQL с помощью пользовательского Dockerfile


Мы также можем установить сервер базы данных PostgreSQL, создав собственный Dockerfile. Ниже мы создадим такой файл, который будет содержать все необходимые команды для установки Postgres, используя CentOS в качестве базового образа:

FROM centos:7
COPY startUpScript.sh /
RUN yum install -y epel-release maven wget \
&& yum clean all \
&& yum install -y  https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm \
&& yum install -y postgresql11-server postgresql11-contrib \
&& chown root /startUpScript.sh \
&& chgrp root /startUpScript.sh \
&& chmod 777 /startUpScript.sh
CMD ["/bin/bash","-c","/startUpScript.sh && tail -f /dev/null"]

В приведённом выше Dockerfile мы использовали startUpScript.sh для запуска сервера базы данных PostgreSQL после успешной установки. Давайте также рассмотрим файл startUpScript.sh:

#!/bin/bash
su -l postgres -c /usr/pgsql-11/bin/initdb
su -l postgres -c "/usr/pgsql-11/bin/pg_ctl -D /var/lib/pgsql/11/data -l /tmp/pg_logfile start"
createdb -U postgres baeldung

В startUpScript.sh мы сначала инициализировали базу данных PostgreSQL, а затем создали фиктивную базу данных под условным именем baeldung.

4. Установка pgAdmin на Docker


Итак, сервер PostgreSQL активен и работает на порте 5432. Теперь мы установим pgAdmin — инструмент с веб-интерфейсом, используемый для управления базами данных и сервисами PostgreSQL. pgAdmin можно использовать для выполнения SQL-запросов к базам данных PostgreSQL.

Мы можем использовать pgAdmin для выполнения всех запросов из пользовательского интерфейса, и для этого нам нужно извлечь образ pgAdmin с помощью следующей команды:

$ docker pull dpage/pgadmin4:latest
latest: Pulling from dpage/pgadmin4
40e059520d19: Pull complete
...
6d23acfae6ef: Pull complete
Digest: sha256:f820e5579857a7210599f998c818777a2f6f39172b50fbeb2faaa1a70413e9ac
Status: Downloaded newer image for dpage/pgadmin4:latest
docker.io/dpage/pgadmin4:latest

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

$ docker run --name pgadmin-baeldung -p 5051:80 -e "PGADMIN_DEFAULT_EMAIL=user@baeldung.com" -e "PGADMIN_DEFAULT_PASSWORD=baeldung" -d dpage/pgadmin4

В команде выше мы предоставили PGADMIN_DEFAULT_EMAIL и PGADMIN_DEFAULT_PASSWORD в качестве переменной окружения для контейнера pgadmin-baeldung:


С помощью графического интерфейса pgAdmin мы можем легко получать доступ к нашим базам данных PostgreSQL. Просто установите соединение с сервером PostgreSQL с помощью pgAdmin и залогиньтесь.

5. Резервное копирование и восстановление данных


В этом разделе мы научимся создавать резервные копии и восстанавливать данные в PostgreSQL с помощью команд Docker.

Сначала, чтобы создать резервную копию данных, давайте создадим фиктивную базу данных baeldung и таблицу baeldungauthor:

$ createdb -h localhost -p 5432 -U baeldung baeldung

Команда для создания таблицы выглядит следующим образом:

CREATE TABLE baeldungauthor (
   AUTHOR_ID INT PRIMARY KEY     NOT NULL,
   AUTHOR_NAME           TEXT    NOT NULL,
   AUTHOR_AGE            INT     NOT NULL,
   AUTHOR_LEVEL        INT     NOT NULL
);

Укажем созданную таблицу в базе данных:

psql -U baeldung -d baeldung -c "\d"
              List of relations
 Schema |      Name      | Type  |   Owner    
--------+----------------+-------+------------
 public | baedlungauthor | table | baeldung
(1 row)

Теперь воспользуемся следующей командой, чтобы получить подробную схему таблицы baeldungauthor:

psql -U baeldung -d baeldung -c "\d baedlungauthor"
              Table "public.baedlungauthor"
    Column    |  Type   | Collation | Nullable | Default
--------------+---------+-----------+----------+---------
 author_id    | integer |           | not null |
 author_name  | text    |           | not null |
 author_age   | integer |           | not null |
 author_level | integer |           | not null |
Indexes:
    "baedlungauthor_pkey" PRIMARY KEY, btree (author_id)

Теперь у нас есть база данных и таблица. Давайте рассмотрим команду резервного копирования для контейнера Docker:

$ docker exec -t postgresql pg_dumpall -c -U baeldung > dump.sql

Здесь мы использовали команду pg_dumpall для резервного копирования базы данных baeldung (Это стандартный инструмент PostgreSQL для таких задач). Мы также указали имя пользователя сервера БД для доступа к привилегиям.

Теперь давайте проверим команду для восстановления базы данных:

$ cat dump.sql | docker exec -i postgresql psql -U baeldung

Таким образом, мы восстановили все таблицы базы данных baeldung с помощью команды psql.

6. Заключение


В этой статье мы научились устанавливать базу данных PostgreSQL с помощью контейнера Docker и изучили каждый шаг по извлечению, настройке и запуску Docker-контейнера Postgres. Кроме того, мы разобрали оба способа доступа к серверу базы данных PostgreSQL. Сначала, для доступа к серверу запущенному в контейнере Docker — мы использовали pgAdmin, а затем, для выполнения запросов к БД — применили psql.

Подводя итог, мы запустили контейнер Docker с базой данных PostgreSQL, используя публичный образ Postgres, представленный на Docker Hub. Мы также создали собственный Dockerfile для установки сервера PostgreSQL в Docker-контейнер.

Наконец, мы рассмотрели резервное копирование и восстановление данных в базе данных PostgreSQL с помощью контейнера Docker.

Спасибо за внимание!

Комментарии (11)


  1. Solopov
    02.09.2022 15:35

    Самое интересное при работе PG в docker - это переход на новую версию PG.
    Причем если образ postgres:latest, то контейнер может и сам обновится, и далее все "сломается". Что дальше делать с данными ?
    Переход на новую версию на хост системы подробно описан в документации, а тут ?


    1. AlexGluck
      02.09.2022 16:35
      +1

      Из всех утюгов звучало не использовать тег latest.

      Нормальные люди всегда могут из бекапа поднять.

      Переход сводится к тому, чтобы:
      1. выключить пг
      2. обновить пакеты
      3. включить пг

      С докером это проще:
      1. спулить образ с новой версией (бд ещё работает, а мы уже обновления скачали)
      2. остановить контейнер со старой пг
      3. запустить контейнер с новой и внутренний процесс обновления пройдёт
      4. Можно сразу запустить старый пг, если что-то пошло не так (данные из бекапа или снапшота)

      Ну а ещё можно интересные штуки делать:

      1. после выключения контейнера сделать снапшот тома с данными меньше чем за секунду
      2. восстановление из снапшота меньше чем за секунду
      3. естественная дедупликаия данных
      4. в случае успешного обновления удаление снапшота


      1. Solopov
        04.09.2022 10:12

        3. запустить контейнер с новой и внутренний процесс обновления пройдёт

        А вы пробовали ? Внутренний процесс PG - это pg_upgrade в котором нужно 2 версии PG, текущая и новая. В случае c контейнером в нем нет старой версии.

        Поднять тз бекапа можно, но то иногда оооочень долго.


        1. AlexGluck
          04.09.2022 13:01
          +1

          Запстить из бекапа снапшотом заняло несколько секунд, очень быстро.

          Попробовал, в контейнере есть и старая и новая версии. Пруф.


          1. Solopov
            04.09.2022 21:18

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


    1. Borz
      04.09.2022 13:12

      используйте для обновления докерный pg_upgrade и не используйте образы postgres:latest - используйте postgres:N , где N - номер версии. Например postgres:14


      1. Solopov
        04.09.2022 21:23

        Да, это решение. Но

        1. В статье про это ничего нет, имхо это важно

        2. Это не официальный образ


  1. resetsa
    02.09.2022 15:35
    +3

    Смотрел, смотрел, но смысла статьи так и не понял. А, если только реклама себя любимых.


    1. mSnus
      02.09.2022 23:30

      Куча ключевых слов, вы что, не заметили? Некоторые даже курсивом. В них и смысл.


  1. JordanCpp
    02.09.2022 23:56

    Когда ждать статью, ставим Docker в Docker?:)


    1. Falseclock
      03.09.2022 09:42

      Дак есть же уже... https://hub.docker.com/_/docker

      Docker in Docker!