Бесплатная миграция IT-инфраструктуры в облако

Установка и настройка PostgreSQL в Docker

Александр Бархатов
Александр Бархатов
Технический писатель
16 августа 2024 г.
1312
14 минут чтения
Средний рейтинг статьи: 5

СУБД PostgreSQL — бесплатная объектно-реляционная система управления базами данных с открытым исходным кодом.

Среди достоинств можно выделить возможность ее использования под любые проекты, включая высоконагруженные, широкий формат поддерживаемых типов данных, поддержку ACID (набор требований обеспечивающий сохранность данных), поддержку транзакций и многопользовательской работы. PostgreSQL также часто рассматривают как полноценную замену коммерческим СУБД, таким как Oracle Database и IBM DB2. СУБД является кроссплатформенной и поддерживает установку на все популярные ОС, а также запуск в контейнере Docker.

Предварительные требования

Чтобы запустить СУБД PostgreSQL в контейнере Docker, необходимо следующее:

  • Сервер или виртуальная машина с предустановленной ОС Ubuntu 22.04. Вместо Ubuntu можно использовать любой другой дистрибутив Linux, который поддерживает установку Docker и Docker Compose. С полным списком поддерживаемых дистрибутивов Linux для Docker можно ознакомиться по ссылке.

  • Установленные Docker и Docker Compose. Официальная документация по установке Docker и Docker Compose доступна по ссылке. Мы рассмотрим установку этих компонентов ниже.

Создание облачного сервера

Чтобы арендовать облачный или выделенный сервер, у вас должен быть аккаунт в Timeweb Cloud. После того, как учетная запись была создана и активирована, можно арендовать облачный сервер. 

1) Переходим на страницу авторизации и входим в аккаунт при помощи логина или адреса электронной почты и пароля.

2) После успешной авторизации отобразится панель управления текущего проекта. Переходим в раздел «Облачные серверы» и нажимаем «Создать» или «Добавить».

3) Выбираем операционную систему, которая будет установлена на сервер. В нашем случае нам необходима Ubuntu версии 22.04.

4) Выбираем регион, в котором будет находиться наш сервер. Выбирать рекомендуется тот регион, который ближе всего находится к вам физически. У каждого доступного региона справа вверху отображается ping, т.е. время, необходимое для передачи данных с вашего компьютера на сервер. Чем меньше указанное время, тем быстрее будет осуществляться передача данных.

Image5

5) Для сервера необходимо выбрать конфигурацию из числа предложенных, также можно выбрать произвольные характеристики. Воспользуемся следующей конфигурацией — двухъядерный процессор и 40 ГБ жесткого диска. Выбираем соответствующий тариф:

Image6

6) Далее можно выбрать, будет ли сервер доступен из внешний сети или же только из частной сети. Также серверу можно назначить публичный IP-адрес, чтобы подключаться к нему из сети интернет. Публичный IP-адрес не является обязательным к использованию, но без него вы не сможете обращаться к серверу из внешней сети или выходить во внешнюю сеть с сервера.

7) Дополнительно можно воспользоваться услугами по резервному копированию и защиты от DDoS-атак (опция доступна только в Москве и Санкт-Петербурге).

Image4

8) Чтобы не входить на сервер используя пароль пользователя, можно заранее загрузить SSH-ключ.

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

10) Для создания сервера необходимо нажать на кнопку «Заказать».

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

cloud

Установка Docker и Docker compose в Ubuntu 22.04

Установим Docker и Docker compose. Все команды, перечисленные ниже, необходимо выполнить от имени root-пользователя или от имени обычного пользователя с правами sudo.

1) Обновляем репозитории ОС и устанавливаем дополнительные утилиты:

apt update && apt -y install ca-certificates curl

2) Далее устанавливаем права доступа на директорию /etc/apt/keyrings, используя утилиту install:

install -m 0755 -d /etc/apt/keyrings

3) Для того чтобы верифицировать официальный Docker-репозиторий, необходимо скачать GPG-ключ от репозитория Docker. GPG-ключи используются не только для шифрования, но и для проверки на подлинность (в том числе и для репозиториев). Скачаем ключ при помощи утилиты curl:

curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc

4) Задаем права доступа к скачанному файлу:

chmod a+r /etc/apt/keyrings/docker.asc

5) Прописываем официальный репозиторий от Docker:

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
tee /etc/apt/sources.list.d/docker.list > /dev/null

6) Устанавливаем Docker вместе с необходимыми зависимостями:

apt update && apt -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Чтобы проверить наличие Docker compose в системе, достаточно выполнить команду:

docker compose version

Если команда отобразила версию, то утилита установлена правильно.

Описание образа PostgreSQL

Компания PostgreSQL предоставляет собственный образ PostgreSQL который хранится в репозитории Docker Hub и доступен по ссылке. Также на Гитхабе можно найти еще более подробное описание. 

PostgreSQL поддерживает следующие архитектуры:

  • amd64
  • arm32v5
  • arm32v6
  • arm32v7
  • arm64v8
  • i386
  • mips64le
  • ppc64le
  • riscv64
  • s390x

Далее в статье мы подробно рассмотрим необходимые параметры для использования СУБД.

Используемые переменные окружения

PostgreSQL поддерживает следующие встроенные переменные окружения:

  • POSTGRES_USER — создает пользователя для доступа к базе данных и одноименную базу данных. Если не задать пользователя, то по умолчанию всегда будет создаваться пользователь с именем postgres.

  • POSTGRES_PASSWORD — задает пароль для пользователя базы данных. Переменная POSTGRES_PASSWORD является обязательной к использованию при запуске контейнера — если ее не задать, то контейнер не будет запущен и перейдет в статус Exited.

  • POSTGRES_DB — создает новую базу данных с заданным именем. Если не создавать новую базу данных, то по умолчанию  будет создана база данных, названная именем создаваемого пользователя.

  • POSTGRES_INITDB_ARGS — используется для добавления опций в postgres_initdb. Список поддерживаемых опций доступен по ссылке.

  • POSTGRES_INITDB_WALDIR — указывается конкретная директория, где будет храниться журнал транзакций PostgreSQL.

  • POSTGRES_HOST_AUTH_METHOD —  позволяет изменять метод аутентификации для пользователей.

  • PGDATA — указывается директория для хранения файлов базы данных.

Запускаем PostgreSQL с минимальными опциями

Для начала рассмотрим быстрый запуск PostgreSQL, используя минимальную конфигурацию. Чтобы запустить PostgreSQL в Docker контейнере, необходимо воспользоваться следующей командой:

docker run --name simple_postgres_instance -e POSTGRES_PASSWORD=4Vd59Ab4dt -d postgres:16

Где:

  • --name simple_postgres_instance — опция --name задает имя для запускаемого контейнера. В данном примере у запущенного контейнера будет имя simple_postgres_instance. Опция --name не является обязательной. Если не задавать имя для контейнера вручную, то демон Docker автоматически назначит свое имя используя два слова — прилагательное и имя актера, певца или известной личности. Ознакомиться с используемыми словами можно по ссылке
  • -e POSTGRES_PASSWORD=4Vd59Ab4dt — использование встроенной переменной с именем POSTGRES_PASSWORD, в которой указан пароль для создаваемого пользователя postgres. В данном случае пользователю postgres будет назначен пароль 4Vd59Ab4dt. При помощи этих данных (логина и пароля) можно подключаться к серверу PostgreSQL. Использование переменной POSTGRES_PASSWORD является обязательным условием для запуска PostgreSQL в контейнере Docker вне зависимости от типа конфигурации. Если попытаться запустить контейнер без переменной POSTGRES_PASSWORD, то в логах контейнера будет следующая ошибка:

Image1

  • -d — опция d (сокращение от слова detach) запускает контейнер в режиме «демона» — в фоновом режиме. Если не использовать опцию d, то после запуска контейнера он перейдет в режим Foreground (режим переднего плана). В этом режиме консоль запускаемого контейнера подключается к стандартным потокам ввода, вывода и потока ошибок. При нажатии на сочетание клавиш Ctrl + Z контейнер будет завершен со статусом Exited.
  • postgres:16 — имя и тег используемого образа PostgreSQL. Со всеми общедоступными тегами можно ознакомиться на Docker Hub по ссылке. В данном примере тег 16 означает что будет использоваться 16 версия PostgreSQL. Однако имя тега может не отражать его реальное назначение. Если не задать тег, то по умолчанию всегда будет использоваться тег latest. В целях безопасности никогда не используйте такой тег — в нем может содержаться неисправная версия или версия содержащая потенциальные угрозы безопасности.

После того как контейнер будет успешно запущен, можно получить доступ до оболочки psql. Для этого достаточно запустить контейнер при помощи команды:

docker exec -it simple_postgres_instance psql -h localhost -U postgres -p 5432

Где:

  • psql — команда, которая будет выполнена при входе в контейнер. В данном примере будет открыт интерфейс утилиты psql.
  • -h localhost — указывается адрес СУБД. Если необходимо подключиться к базе текущего запущенного контейнера, то необходимо указать адрес localhost. Также можно подключаться к удаленным СУБД, используя IP-адрес или доменное имя. При подключении к удаленным СУБД необходимо убедиться в наличии сетевого доступа.
  • -U postgres — пользователь из-под имени которого будет осуществлено подключение к базе данных. Для того чтобы создать пользователя под другим именем, при старте контейнера необходимо воспользоваться переменной POSTGRES_USER, в значении которой указано нужное имя пользователя.
  • -p 5432 — порт, который использует запущенный экземпляр PostgreSQL. Порт 5432 используется по умолчанию.

Запускаем PostgreSQL при помощи Docker Compose

Помимо запуска СУБД при помощи команды docker run в standalone-режиме (когда запускается только один контейнер), PostgreSQL также можно запустить с помощью docker compose. В примере ниже приведен пример файла docker-compose.yml:

version: '3.9'

services:

  db:
    image: postgres:16
    ports:
         - 5432:5432
    restart: always
    environment:
POSTGRES_USER=new_usr1
POSTGRES_PASSWORD=P@$$w0rD
POSTGRES_DB=usr1_db

В файле выше будет запущен PostgreSQL 16 версии с проброшенным портом 5432, который используется по умолчанию. Также будет задействован механизм тома (volumes), в котором хранятся данные базы данных (в контейнере они будут храниться по пути /var/lib/postgresql/data). Также при создании контейнера будет создан новый пользователя с именем usr1, с паролем P@$$w0rD и новой базой данных usr1_db.

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

docker compose up -d

Команду выше необходимо выполнять из директории, в которой находится docker-compose.yml.

Проброс портов для удаленного доступа к PostgreSQL

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

-p порт_который_будет_доступен_извне:порт_сервиса

Под портом сервиса подразумевается порт, который используется программой. Пробросим порт 5432, используемый PostgreSQL по умолчанию, сопоставляя его с портом 5432:

docker run --name postgres_instance2 -p 5432:5432 -e POSTGRES_USER=new-admin -e POSTGRES_PASSWORD=4Vd59Ab4dt  -e POSTGRES_DB=admin-database -d postgres:16

После запуска контейнера доступ до базы данных можно получить с другого хоста или при помощи программы для удаленного подключения, например, DBeaver. В качестве IP-адреса необходимо ввести IP-адрес сервера и проброшенный порт (в данном случае это порт 5432).

Проброс конфигурационных файлов внутрь контейнера

Если для работы PostgreSQL требуется использовать измененную конфигурацию, то ее можно использовать в контейнере путем «проброса» внутрь контейнера. Для этого используется функционал по монтированию (mount) файлов, при помощи которого файлы, физически расположенные на хостовой операционной системе, «пробрасываются» внутрь контейнера. При этом, если контейнер будет полностью удален, то пробрасываемый файл останется, т.к. он находится в хостовой файловой системе.

Рассмотрим конкретный пример. Основной конфигурационный файл СУБД PostgreSQL называется postgresql.conf и располагается в директории /etc/postgresql. Предположим, необходимо внести некоторые изменения в конфигурационный файл postgresql, далее измененный файл необходимо пробросить внутрь запускаемого контейнера, чтобы он использовал измененную конфигурацию. Для проброса файлов используется опция -v. Команда для запуска контейнера с новым конфигурационным файлом:

docker run -d --name postgres-configured -v "$PWD/my-postgres.conf":/etc/postgresql/postgresql.conf -e POSTGRES_PASSWORD=StrongPassword12345 postgres -c ‘config_file=/etc/postgresql/postgresql.conf’

Где:

  • -v "$PWD/my-postgres.conf":/etc/postgresql/postgresql.conf — опция -v отвечает за монтирование файла с хоста внутрь контейнера. Первая часть $PWD/my-postgres.conf означает, что будет проброшен файл с именем my-postgres.conf, который находится на хостовой операционной системе, вторая часть /etc/postgresql/postgresql.conf означает, что пробрасываемый файл будет располагаться по следующему пути — /etc/postgresql/.

По такому же принципу можно пробрасывать другие файлы для других сервисов (Nginx, MySQL, Apache Kafka и т.д.).

Организация хранения файлов базы данных

Все запускаемые контейнеры Docker являются эфирными — это означает что их можно создавать и удалять в любой момент. Особенностью этого процесса является то, что при удалении контейнера все данные, которые находятся внутри него, будут удалены. Это правило не распространяется на те данные, которые были проброшены в контейнер при помощи опции монтирования (mount) или при использовании томов данных, т.к. такие данные хранятся на хостовой операционной системе. При использовании PostgreSQL в контейнере возникает вопрос хранения файлов базы данных. Для решения данной проблемы можно использовать механизмов томов (volumes), который хранит данные контейнера на хостовой операционной системе в отдельной директории. Как и при использовании функционала по пробросу файлов, данные из томов не удаляются при перезапуске или удалении контейнера. Для того чтобы начать использовать тома для хранения файлов базы данных, необходимо выполнить следующее:

1) На хостовой ОС создадим том (volume):

docker volume create hs1
  • hs1 — имя создаваемого тома.

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

docker volume inspect hs1

По умолчанию все тома хранятся в /var/lib/docker/volumes.

2) Запускаем контейнер с PostgreSQL, используя ранее созданный том с именем hs1 и примонтировав его к директории /var/lib/postgresql/data, которая находится внутри контейнера (в данной директории по умолчанию хранятся файлы базы данной PostgreSQL):  

docker run -d \
  --name postgres_with_volume \
  -e POSTGRES_PASSWORD=LVALaWKNIKoU \
  -v hs1:/var/lib/postgresql/data \
postgres:16

3) Проверим правильность работы механизма томов:

docker exec -it postgres_with_volume  psql -U postgres

4) Далее создаем базу данных demo:

CREATE DATABASE demo;

5) Подключаемся к demo:

\c demo

6) Создадим таблицу с двумя полями:

CREATE TABLE users (id INT PRIMARY KEY, name VARCHAR(255));

7) Добавляем запись в таблицу:

INSERT INTO users (id, name) VALUES (25, 'alex');

8) Выходим из оболочки psql:

\q

И из контейнера:

exit

9) Удаляем запущенный контейнер:

docker rm -f postgres_with_volume

10) Теперь просмотрим содержимое ранее используемого тома с именем hs1. Для этого выполним команду ls:

ls -l /var/lib/docker/volumes/hs1/_data

Image8

Как можно увидеть на скриншоте выше, все файлы базы данной сохранены, несмотря на удаление контейнера.

11) Запустим контейнер, примонтировав том hs1:

docker run -d \
  --name postgres_with_volume \
  -e POSTGRES_PASSWORD=LVALaWKNIKoU \
  -v hs1:/var/lib/postgresql/data \
  postgres:16

12) Установим подключение к оболочке контейнера: 

docker exec -it postgres_with_volume psql -U postgres

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

\l

Image2

Установим подключение к БД demo:

\c demo

И выполним запрос на выборку данных:

SELECT * FROM users;

Image3

Вот как можно использовать механизм топов в docker compose:

version: '3.9'

volumes:
  ns2:

services:

  db:
    image: postgres:16
    ports:
         - 5432:5432
    volumes:
        - ns2:/var/lib/postgresql/data
    restart: always
    environment:
POSTGRES_USER=new_usr1
POSTGRES_PASSWORD=P@$$w0rD
POSTGRES_DB=usr1_db

Использование языковых стандартов — locale

СУБД поддерживает функционал по настройке языковых стандартов, именуемых locales (локали). Локаль применяют, например для правильной сортировки символов или форматирования чисел. Рассмотрим два способа, как можно настроить локаль: в файле Dockerfile и в standalone -контейнере.

Пример по использованию локали в Dockerfile:

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

Еще настроить локаль можно в standalone-образах, использующих в качестве базового образа дистрибутив Alpine. Запускаемая команда будет следующей для использования русской локали:

docker run -d -e LANG=ru_RU.utf8 -e POSTGRES_INITDB_ARGS="--locale-provider=icu --icu-locale=ru-RU" -e POSTGRES_PASSWORD=782LMwVX8# postgres:16-alpine
Подготовили для вас выгодные тарифы на облачные серверы

Заключение

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

Хотите внести свой вклад?
Участвуйте в нашей контент-программе за
вознаграждение или запросите нужную вам инструкцию
img-server
16 августа 2024 г.
1312
14 минут чтения
Средний рейтинг статьи: 5
Пока нет комментариев