Установка PostgreSQL с помощью Docker

В этом руководстве мы научимся устанавливать PostgreSQL с помощью Docker. Обычно мы запускаем контейнер Docker, используя публичный образ Docker, или берём предварительно настроенные Docker-образы сервера баз данных PostgreSQL из Docker Hub. Здесь же мы продемонстрируем, как PostgreSQL можно установить, настроить и запустить на Docker.
Сначала запустим контейнер Docker с базой данных PostgreSQL, используя публичный образ PostgreSQL. Позже мы создадим пользовательский Dockerfile для установки сервера PostgreSQL в контейнер Docker. Также мы научимся создавать резервные копии и восстанавливать базу данных с помощью контейнера Docker.
Оглавление:
- Знакомство с базой данных PostgreSQL
- Установка PostgreSQL с помощью публичного образа
- Установка PostgreSQL с помощью пользовательского Dockerfile
- Установка pgAdmin на Docker
- Резервное копирование и восстановление данных
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.
Спасибо за внимание!
- Блог компании FirstVDS
- PostgreSQL
Полное руководство по установке и настройке PostgreSQL в Docker
(1).jpg)
Docker – это платформа, которая позволяет создавать, упаковывать и запускать приложения в контейнерах. Контейнеры обеспечивают изоляцию приложений и их зависимостей, что делает их легко переносимыми и масштабируемыми.
Docker упрощает разработку, развертывание и управление приложениями, а также способствует снижению конфликтов окружений.
Вдобавок к этому, он позволяет разработчикам сосредоточиться на создании качественного ПО и облегчает DevOps-практики для более быстрой и надёжной доставки приложений.
Что такое PostgreSQL
(1).jpg)
PostgreSQL (PostgreSQL Database Management System) – это объектно-реляционная система управления базами данных (СУБД) с открытым исходным кодом.
Основные характеристики PostgreSQL:
- Расширяемость. PostgreSQL предоставляет множество функций и возможностей, а также поддерживает различные расширения, что позволяет разработчикам создавать свои пользовательские типы данных, функции и процедуры.
- Объектно-реляционная модель. PostgreSQL сочетает в себе функциональность реляционных баз данных и объектно-ориентированных баз данных. Он не только поддерживает таблицы, представления, индексы, триггеры и хранимые процедуры, но и позволяет определять собственные пользовательские типы данных.
- ACID-транзакции. Данная СУБД обеспечивает целостность данных благодаря поддержке ACID-транзакций.
ACID – это набор требований, которые обеспечивают сохранность ваших данных. В аббревиатуру входят: Atomicity (Атомарность), Consistency (Согласованность), Isolation (Изоляция) и Durability (Долговечность).
- Многопоточность и параллелизм. PostgreSQL может эффективно работать с множеством параллельных запросов и потоков, обеспечивая высокую производительность на многопроцессорных системах.
- JSON-поддержка. PostgreSQL имеет встроенную поддержку для хранения и работы с данными формата JSON.
- Поддержка множества программных языков. PostgreSQL может использоваться с различными языками программирования. Например, с C/C++, Python , Java, Perl , Ruby и другими, что делает эту систему универсальной и удобной для разработки.
- Географические и геометрические типы данных. PostgreSQL прекрасно подходит для запуска геопространственных приложений, так как даёт возможность хранить и работать с географическими и геометрическими данными.
Иными словами, PostgreSQL широко используется в различных областях, включая веб-приложения, геоинформационные системы, хранение и обработка больших объёмов данных и многое другое. Благодаря своим многочисленным особенностям, эта СУБД разработчиков и компаний по всему миру.
Зачем использовать PostgreSQL в контейнере
Использование PostgreSQL в контейнере предоставляет высокую степень изоляции и портабельности базы данных (БД). Контейнеры позволяют упаковать PostgreSQL и все его зависимости в одну изолированную среду, что значительно упрощает процесс развертывания и управления базой данных, а также обеспечивает предсказуемость работы приложений, использующих эту БД.
Однако это одни из многих причин использовать PostgreSQL в контейнере. Этот способ:
- обеспечивает изолированную среду для базы данных, что предотвращает конфликты с другими компонентами системы и обеспечивает стабильность работы;
- предоставляет возможность запускать PostgreSQL на различных хостах или облачных сервисах без изменения конфигурации;
- упрощает управление версиями PostgreSQL и позволяет быстро менять образы для обновления или отката БД;
- упрощает процесс развёртывания и обеспечивает предсказуемость при тестировании, разработке и масштабировании;
- способствует применению DevOps-практик и автоматизации процессов разработки и обновления БД;
- обеспечивает отказоустойчивость и даёт быстро восстановить PostgreSQL из резервной копии при сбоях.
Аренда сервера
Для работы с такой системой управления базами данных, как PostgreSQL, а тем более её разворачивания в Docker может потребоваться определённый объём ресурсов на сервере.
В таком случае поручите хранение своих данных проверенному партнёру! RU-CENTER предлагает аренду физического сервера, который обеспечит безопасность вашей информации. Мощное устройство в московском дата-центре гарантирует надёжность, а профессиональное обслуживание и поддержка 24/7 обеспечат бесперебойную работу ваших проектов.
(4).png)
Для тех же, кто ищет идеальное виртуальное решение, RU-CENTER предлагает VPS/VDS хостинг на Linux. Наша команда профессионалов готова обеспечить непрерывную поддержку и круглосуточное обслуживание, чтобы вы могли сосредоточиться на более важных задачах и развитии своего проекта.
(4).png)
Установка PostgreSQL в Docker из образа
Установка PostgreSQL в Docker осуществляется путём создания и запуска контейнера на основе официального Docker-образа PostgreSQL, который предоставляется командой Docker.
Вот простая инструкция по установке PostgreSQL в Docker из официального образа:
- Если у вас ещё нет Docker, убедитесь, что установили его на свой сервер. Вы можете скачать и установить платформу для своей операционной системы, следуя инструкциям на официальном сайте Docker или воспользовавшись нашим руководством.
- Откройте командную строку или терминал и выполните команду для поиска официального образа PostgreSQL в Docker Hub:
docker search postgres
Перед вами появится список доступных образов. Выберите тот, который соответствует вашим требованиям. Обычно, для базовой установки вы можете использовать официальный образ с именем «postgres».
- Загрузите выбранный образ PostgreSQL с помощью команды:
docker pull postgres
Готово! Теперь у вас установлен и работает PostgreSQL в контейнере Docker с именем «doc_postgres».
Запуск контейнера PostgreSQL в Docker
(2).jpg)
- После того, как образ будет загружен, вы сможете создать контейнер из него. Например, чтобы создать контейнер с именем «doc_postgres», используя образ PostgreSQL, выполните следующую команду:
docker run —name doc_postgres -e POSTGRES_PASSWORD=mypassword -d postgres
- «—name dc_postgres» задаст имя контейнера (в данном случае «doc_postgres»);
- «-e POSTGRES_PASSWORD=mypassword» задаст пароль для пользователя «postgres»;
- аргумент «-d» означает, что контейнер будет запущен в фоновом режиме.
- Чтобы проверить, что контейнер успешно запущен, выполните команду:
В выводе вы увидите список всех запущенных контейнеров. Если запуск был произведён корректно, в списке появится контейнер с именем «doc_postgres» со статусом «Up».
Контейнер будет запущен в фоновом режиме, и СУБД PostgreSQL будет доступна для подключения.
Как подключиться к PostgreSQL в контейнере
- Если вы хотите подключиться к PostgreSQL внутри контейнера с помощью клиента, например, «psql», можете выполнить следующую команду:
docker exec -it doc_postgres psql -U postgres
После выполнения команды, вы будете подключены к базе данных PostgreSQL в контейнере. Там можно выполнять SQL-запросы и свободно работать с БД.
- Когда контейнер вам станет не нужен, остановите его простой командой:
docker stop doc_postgres
Вы также можете остановить и сразу удалить данный контейнер:
docker rm -f doc_postgres
Важно! При удалении контейнера данные внутри него также будут удалены. Если вы хотите сохранить их, настройте тома для хранения этих данных вне контейнера.
Теперь вы знаете, как подключиться к PostgreSQL в контейнере Docker и выполнять запросы к базе данных.
Если у вас возникли проблемы при подключении, убедитесь, что:
- контейнер PostgreSQL запущен;
- правильно указаны имя контейнера и имя пользователя для подключения.
Запуск PostgreSQL с помощью docker-compose
Запуск PostgreSQL с помощью Docker Compose – это наиболее удобный способ управления контейнерами. Docker Compose позволяет запускать несколько контейнеров одновременно, а также настраивать их взаимодействие и зависимости.
Чтобы выполнить запуск PostgreSQL с помощью Docker Compose, выполните несколько шагов, описанных ниже.
Шаг 1. Установка Docker Compose
Убедитесь, что вы установили Docker Compose на свой компьютер или сервер. Плагин Docker Compose поставляется вместе с Docker для Windows и Mac, но для Linux вы должны установить его отдельно.
В этом шаге мы рассмотрим загрузку Docker Compose из репозитория.
- Обновите пакеты и установите последнюю версию Docker Compose:
Ubuntu/Debian:
sudo apt-get update
sudo apt-get install docker-compose-plugin
CentOS:
sudo yum update
sudo yum install docker-compose-plugin
- Проверьте, корректно ли прошла установка, проверив версию:
docker compose version
Готово! Вы установили плагин Docker Compose в операционные системы Ubuntu, Debian и CentOS.
Также вы можете ознакомиться с процессом установки вручную в официальной документации Docker.
Шаг 2. Запуск PostgreSQL
- Создайте новый файл с именем «docker-compose.yml» и откройте его для редактирования. В этом файле вы определите параметры запуска PostgreSQL.
Содержание «docker-compose.yml» для запуска PostgreSQL должно быть примерно следующим:
- Откройте командную строку или терминал и перейдите в каталог, где находится ваш файл «docker-compose.yml». Затем выполните следующую команду:
docker-compose up -d
Команда «docker-compose up -d» загрузит образ PostgreSQL, создаст и запустит контейнер на основе определения из ранее созданного файла, а аргумент «-d» запустит контейнеры в фоновом режиме.
- Чтобы убедиться, что контейнер с PostgreSQL успешно запущен, выполните команду:
- Если вы захотите отключить данный контейнер, то можете остановить и удалить его командой:
Важно! Данные внутри контейнера останутся на вашем сервере, только если вы настроили том для PostgreSQL.
Заключение
В этой статье мы рассмотрели установку и настройку PostgreSQL с использованием Docker.
Контейнеризация делает процесс работы с базами данных более предсказуемым и эффективным, позволяя быстро масштабировать и управлять PostgreSQL в различных сценариях. Этот подход особенно полезен для разработчиков и DevOps-специалистов и обеспечивает удобную среду для работы с PostgreSQL.
Глава 6. Добавляем базу данных: Postgres
Не знаю как вы, но я очень вдохновлён нашим развитием. Мы постепенно совершенствуем свои навыки и теперь в шаговой доступности от своего приложения Dockerized Rails имеющего все те возможности, которые мы применяем когда запускаем Rails локально.
Тем не менее есть одно явное упущение: мы не настроили базу данных. Подавляющему большинству приложений Rails требуется постоянное хранилище.
В этой главе мы исправим его, основываясь на своём опыте добавления сервера Redis, для подключения базы данных Postgres.
При чтении данной главы помните об сохранении в памяти всей большой картины. Изучаемые вами навыки применимы ко всем службам, которые вы можете пожелать добавить в своё приложение, будь то запуск фоновых заданий (таких как Sidekiq), Elasticsearch или некий интерфейс JavaScript для API Rails.
Запуск сервера Postgres
Для применения в своём приложении Rails мы хотим запустить некий сервер Postgres. Этот процесс очень похож на то как мы добавляли Redis.
В своей предыдущей главе мы начали своё ознакомление с тем как запускать Redis при помощи docker run . Однако теперь, когда у нас уже имеется некий опыт по добавлению служб, давайте позаботимся о сохранности колёс и перепрыгнем сразу к настройке Postres при помощи Compose.
Давайте добавим в свой файл docker-compose.yml Postgres:
version: '3' services: web: build: . ports: - "3000:3000" volumes: - .:/usr/src/app redis: image: redis » database: » image: postgres » environment: » POSTGRES_USER: postgres » POSTGRES_PASSWORD: some-long-secure-password » POSTGRES_DB: myapp_development
Мы определили некую новую службу database применив официальный образ postgres . Мы полагаемся на установленную по умолчанию в этом образе инструкцию CMD — CMD [«postgres»] которая запустит наш сервер Postgres.
Как и в случае с redis нашей новой службе database не требуется установление соответствия порта или тома. Мы не хотим в своём приложении наличия доступа к нашей базе данных извне и нам не требуется монтировать какие бы то ни было файлы в этот контейнер Postres.
Нам приходится, тем не менее, определять некое новое свойство с названием environment . Вы скорее всего догадались что оно делает: оно указывает Docker на необходимость настройки последующих переменных среды внутри этого контейнера. Здесь мы определяем что POSTGRES_USER должен быть установлен в postgres ; POSTGRES_PASSWORD следует определить значением some-long-secure-password ; а POSTGRES_DB надлежит настроить на myapp_development .
Зачем мы это сделали?
В точности как и версия Postres без Docker позволяет вам определять некие переменные окружения, то же самое справедливо идля нашей версии с Docker. Когда запускается Postres, если установлена POSTGRES_USER , именно это значение будет применяться в качестве имени учётной записи для суперпользователя. Аналогично, если установлен POSTGRES_PASSWORD , он будет применяться в качестве пароля данного суперпользователя. Наконец, если установлена POSTGRES_DB , именно она будет применяться в качестве базы данных по умолчанию, которая создаётся при запуске.
Не очень разумно иметь пароль нашей базы данных в данном файле docker-compose.yml : этот файл должен фиксироваться контролем версий, но существует риск для безопасности фиксации файлов, содержащих секретные коды. Мы вернёмся к этому вопросу позднее. Помимо этого, чисто технически, нам не требуется устанавливать POSTGRES_USER , так как это значение имеется у нас установленным по умолчанию. Тем не менее, я включил его, поскольку хорошей практикой является делать такие вещи настраиваемыми.
Хорошо. Имея эти обновления docker-compose.yml , мы можем запустить Postres:
$ docker-compose up -d database
Мы запустили свою службу database в отключённом режиме (detached). Вы можете убедиться что она поднята и исполняется при помощи:
$ docker-compose ps Name Command State Ports ---------------------------------------------------------------------------- myapp_database_1 docker-entrypoint.sh pos… Up 5432/tcp myapp_redis_1 docker-entrypoint.sh red… Up 6379/tcp myapp_web_1 bin/rails s -b 0.0.0.0 Up 0.0.0.0:3000->3000/tcp
Теперь у нас имеются три контейнера для нашего приложения и мы можем видеть своё новое прибавление — нашу базу данных — она исполняется.
В качестве дальнейшей проверки мы можем просмотреть вывод контейнера этой базы данных:
$ docker-compose logs database Attaching to myapp_database_1 . database_1 | PostgreSQL init process complete; ready for start up. database_1 | database_1 | 2019-01-15 10:07:29.394 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432 database_1 | 2019-01-15 10:07:29.394 UTC [1] LOG: listening on IPv6 address "::", port 5432 database_1 | 2019-01-15 10:07:29.397 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432" database_1 | 2019-01-15 10:07:29.409 UTC [60] LOG: database system was shut down at 2019-01-15 10:07:29 UTC database_1 | 2019-01-15 10:07:29.414 UTC [1] LOG: database system is ready to accept connections
Помните, что эта команда отображает регистрационные записи самого контейнера — то есть его вывод отличается от вывода файла регистрационных записей Postgres.
Подключение к Postgres из отдельного контейнера
По мере того вам будет становиться всё удобнее и удобнее при использовании Compose, вы обнаружите что вы доверяете ему делать всё что вам нужно. Скорее всё что вам потребуется для проверки того что некая служба исполняется, это быстрый запуск docker-compose ps (а порой вы даже можете пропускать и это).
Однако так как запуск служб подобных Postres внутри некого контейнера всё ещё внове для нас, давайте проделаем дополнительный шаг вручную подключившись к нему с другого контейнера, в точности как мы проделывали это с Redis. При обучении, по крайней мере для меня лично, это помогало моей уверенности в работе с данными инструментами.
Как это было и в случае с Redis, наш образ postgres поступает с предустановленным psql — клиентом Postgres. Это означает что мы можем зацепиться прицепом к своей новой службе database чтобы запустить одноразовый контейнер на основе своего образа postgres . Тем не менее, вместо применения для этого образа установленную по умолчанию команду, которая запускает сервер Postgres, мы вместо этого исполним некую команду для запуска клиента Postgres.
Мы можем сделать это при помощи такой команды:
$ docker-compose run --rm database psql -U postgres -h database
В ней мы сообщаем: «Запусти новый одноразовый контейнер ( run —rm ) для нашей службы database и исполни внутри него команду psql -u postgres -h database «. Эта команда запустит нужного нам клиента Postres, сообщит ему о необходимости подключения к имеющемуся хосту с именем database от имени пользователя postgres . Мы полагаемся на тот факт, что Compose магическим образом настраивает сетевую среду для нашего приложения с настроенной DNS с тем чтобы указанное название хоста database достигало того контейнера, в котором запущена наша служба database .
Вместо run —rm нам возможно придётся применить exec , который мог бы избежать запуска некого нового контейнера и вместо этого исполнил бы соответствующую команду в уже запущенном контейнере с базой данных. Однако мы намеренно желаем дополнительно убедиться в подключении из иного контейнера.
Когда вы выполните эту команду, вы получите приглашение на ввод пароля:
Password for user postgres:
Пройдите далее и введите some-long-secure-password — тот пароль, который мы установили в своём файле docker-compose.yml . Он должен быть принят и вы получите приглашение psql :
psql (11.1 (Debian 11.1-1.pgdg90+1)) Type "help" for help. postgres=#
Исключительно. Мы подключились к своей службе database , исполняющей Postres и что всё работает как мы и надеялись. Когда вы будете готовы, вы можете покинуть своего клиента psql набрав \q .
Подключение нашего прикладного приложения Rails к Postgres
Только что мы рассмотрели как поднять свою базу данных и достичь её из другого контейнера в своей сетевой среде приложения. Однако прежде чем мы начнём её применять, нам понадобится настроить своё приложение Rails на подключение к ней.
Давайте это сделаем прямо сейчас.
Установка Gem Postgres
Обо всём по порядку. Чтобы заставить наше приложение Rails общаться с Postgres, нам нужно установить соответствующий gem клиента Postgres. Откройте свой Gemfile и обновите его чтобы заменить:
gem 'sqlite3'
gem 'pg', '~> 1.0'
Для реальной установки этого нового gem нам потребуется исполнить bundle install , что мы делаем для перестроения своего образа (мы обсудим это в Главае 9, Расширенное управление Gem. Давайте остановим свой сервер Rails:
$ docker-compose stop web
и после этого выполним повторную сборку своего образа:
$ docker-compose build web Building web Step 1/8 : FROM ruby:2.6 . Step 6/8 : RUN bundle install . Installing pg 1.1.4 with native extensions . Bundle complete! 16 Gemfile dependencies, 69 gems now installed. Bundled gems are installed into `/usr/local/bundle` . Removing intermediate container 9b01b1fa29fc ---> f9e6330d40b6 Step 7/8 : COPY . /usr/src/app/ ---> 70fb0e2e0091 Step 8/8 : CMD ["bin/rails", "s", "-b", "0.0.0.0"] ---> Running in 16cc0923b855 Removing intermediate container 16cc0923b855 ---> d4ffbe8f72d3 Successfully built d4ffbe8f72d3 Successfully tagged myapp_web:latest
Имея установленным gem Postgres, мы можем перейти к настройке своего database.yml .
Создание базы данных нашего приложения
Когда мы создали свой проект Rails, мы сделали это с установками по умолчанию, которые предполагали что мы применяем для своей базы данных sqlite . Теперь, когда мы вместо неё настроили Postgres, выработанный файл database.yml не является верным. Нам необходимо изменить его на нечто более подходящее.
Давайте откроем config/database.yml в неком редакторе и заменим его содержимое следующими настройками Postgres:
default: &default adapter: postgresql encoding: unicode host: username: password: database: pool: 5 variables: statement_timeout: 5000 development:
К счастью, всё выглядит для нас достаточно знакомым.
Мы определили наиболее важные установки ( host , username , password и database ) через переменные среды. Обычно это рассматривается в качестве хорошей практики, однако, как мы увидим позднее, Docker предоставляет некий даже более безопасных подход. В настоящий момент, тем не менее, эти переменные среды не установлены для нашей веб службы web .
Давайте исправим это. Нам придётся изменить свой docker-compose.yml чтобы обеспечить эти переменные настроенными на наш контейнер приложения Rails, подобно следующему:
version: '3' services: web: build: . ports: - "3000:3000" volumes: - .:/usr/src/app » environment: » DATABASE_HOST: database » POSTGRES_USER: postgres » POSTGRES_PASSWORD: some-long-secure-password » POSTGRES_DB: myapp_development redis: image: redis database: image: postgres environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: some-long-secure-password POSTGRES_DB: myapp_development
В нашем мире до Docker мы обычно устанавливали значение DATABASE_HOST в localhost , так как эта база данных исполнялась бы в нашей локальной машине. Здесь, однако, мы определяем название той службы, которая исполняет Postgres: database . Это приводит к разрешению имён для контейнеров службы нашей database благодаря DNS, предоставляемой нашей сетевой средой приложения.
Мы также настраиваем переменные среды POSTGRES_USER , POSTGRES_PASSWORD и POSTGRES_DB на соответствие настройкам для данной службы database ; это означает, что наша служба web будет иметь верные параметры доступа для регистрации в нашей базе данных.
Это должно теперь работать, однако обратим ваше внимание на то, что теперь у нас достаточно много переменных среды и два дубля для служб web и database . Мы также сказали, что не будем включать секретные коды в свой файл docker-compose.yml чтобы мы могли зафиксировать их в своём источнике репозитория. Давайте убъём двух зайцев одним залпом и выделим переменные среды в отдельные файлы.
Прежде всего давайте создадим некие каталоги для хранения своих специфичных для среды настроек:
$ mkdir -p .env/development
Затем создайте соответствующий файл .env/development/web (без какого бы то ни было расширения файла), который сожержит особые для службы web переменные среды:
DATABASE_HOST=database
и другой файл, .env/development/database , содержащий следующее для нашей службы database :
POSTGRES_USER=postgres POSTGRES_PASSWORD=some-long-secure-password POSTGRES_DB=myapp_development
Теперь нам требуется сообщить Compose о необходимости использования этих файлов вместо явной установки значений переменных напрямую. Мы делаем это с помощью соответствующей директивы env_file :
version: '3' services: web: build: . ports: - "3000:3000" volumes: - .:/usr/src/app » env_file: » - .env/development/database » - .env/development/web redis: image: redis database: image: postgres » env_file: » - .env/development/database
Мы могли бы назвать файлы своей среды как угодно, но я выбрал простую осмысленную схему именования. Точно также вы можете применять любую файловую структуру и соглашения об именовании которые вам нравятся для данных файлов переменных среды (в настоящее время в .env ), при условии вы верно ссылаетесь на них в самом файле Compose.
Закончив это небольшое форматирование мы готовы создавать свои базы данных для разработки и тестирования при помощи стандартной команды bin/rails db:create нацелив эту команду на свою службу web :
$ docker-compose run --rm web bin/rails db:create
В данном случае мы воспользовались run --rm вместо exec , так как у нас в данный момент исполняется контейнер web , который не имеет наших вновь добавленных переменных окружения пока мы его не перезапустим. Это сделает наш новый одноразовый контейнер, который и запускает данную команду.
Вы должны обнаружить следующий вывод, отображающий что наша база данных была успешно создана:
Database 'myapp_development' already exists Created database 'myapp_test'
Вы могли бы заметить, что наша база данных myapp_development уже существует, что несколько странно, так как это самый первый раз когда мы просим её создания. Это происходит по той причине, что наш образ postgres автоматически создаст некую базу данных при своём самом первом запуске; если она устанавливается, он применяет своё значение переменной среды POSTGRES_DB в качестве того самого названия для этой таблицы. В нашем случае это myapp_development , и именно по этой причине данная таблица уже имеется.
Отлично, мы уже почти на месте.
Перезапуск нашего сервера Rails
Получив настроенный на применение запущенной в контейнере базы данных Postgres Rails и создав базы данных, окончательный шаг состоит в запуске нашего сервера Rails с вновь установленными настройкой и переменными среды. Однако поскольку Compose будет только повторно применять для сервера имеющийся контейнер, нам придётся в явном виде сообщить ему о необходимости повторной сборки контейнера для своей службы web .
Вот как мы это делаем:
$ docker-compose up -d --force-recreate web
Параметр --force-recreate сообщает: "Собери заново контейнер этой службы."
Теперь двигайтесь далее и зайдите на http://localhost:3000 чтобы убедиться что ваше приложение подключилось к Postgres; если всё хорошо, вы обнаружите стандартный экран запуска Rails, в то время как в случае невозможности подключения ActiveRecord возбудит некую ошибку PG::ConnectionBad .
Мы сделали это - он поднят и исполняется с Postgres.
Рисунок 6-1
Практическое применение базы данных
Мы знаем, что настроив своё приложение Rails для общения с нашей базой данных Postgres это наше приложение Rails успешно запустилось; однако мы полагаемся на отсутствие ошибки в качестве подтверждения того что наша база данных корректно подключилась. Хотя с технической точки зрения это всё что нам требуется, давайте убедимся что всё работает должным образом выполняя взаимодействие с базой данных нашего приложения. Это также позволит нам получить дополнительную практику при разработке своего приложения Rails с Docker через CLI Compose.
Давайте выработаем для своего приложения Rails некий базовый UsersController . Для ускорения мы намерены воспользоваться командой Rails generate scaffold :
$ docker-compose exec web \ bin/rails g scaffold User first_name:string last_name:string invoke active_record create db/migrate/20190115100954_create_users.rb create app/models/user.rb invoke resource_route route resources :users invoke scaffold_controller create app/controllers/users_controller.rb invoke erb create app/views/users create app/views/users/index.html.erb create app/views/users/edit.html.erb create app/views/users/show.html.erb create app/views/users/new.html.erb .
Убедитесь что вы выполнили chown для данных файлов запустив:
$ sudo chown : -R .
За дополнительными подробностями отсылаем к Дополнению A. Владельцы файлов и полномочия.
Теперь нам требуется запустить миграцию для создания своей таблицы Users . web . Вы уже должны начать привыкать к запуску стандартных команд Rails, нацеленных на нашу веб- службу с использованием Compose, в точности так:
$ docker-compose exec web bin/rails db:migrate == 20190115100954 CreateUsers: migrating =================================== -- create_table(:users) ->> 0.0585s == 20190115100954 CreateUsers: migrated (0.0587s) ==========================
Ладно, всё дложно пройти успешно - давайте попробуем. Имея всё ещё запущенным данное приложение, перейдите в своём браузере к http://localhost:3000/users . Вы должны обнаружить знакомые строительные леса (scaffold) Rails и перечисленных пользователей как это показано на следующем рисунке. Убедитесь что у вас имеется возможность создавать и удалять пользователей.
Рисунок 6-2
Великолепно, у нас имеется Postgres целиком настроенный в Compose.
Отделение данных от контейнера
Это прекрасно что мы настроили свою базу данных и поэтому мы теперь способны удерживать данные в своём приложении Rails. Однако, в настоящий момент существует основной провал в том как это работает. Давайте рассмотрим в чём состоит проблема и как его обойти.
Часть философии применения Docker состоит в том, что мы должны рассматривать контейнеры как эфемерные - одноразовые раскручиваемые нами штуки, которые мы применяем и затем удаляем. Однако наша база данных Postgres запускается в некотором контейнере и удерживает наши данные записывая и изменяя файлы на диске внутри самого контейнера. Что произойдёт с нашими данными когда мы удалим свой контейнер базы данных? Ага, вы уже догадались: мы скажем пока- пока всем своим горячо любимым данным. Как- то не совсем то чего бы мы хотели.
Теперь, когда мы намерены сохранять в своей базе данных важную информацию, нам необходимо подумать об этом слегка более аккуратно.
В точности как и в своём коде, в котором мы пытаемся отделить часто изменяющиеся вещи от тех которые не так этому подвержены, мы желаем отделить свои данные от самих контейнеров, которые их создают и применяют их. Наши данные следует хранить отдельно от самих контейнеров, которые их и исполняют. Таким образом мы можем удалять, уничтожать и воссоздавать такой контейнер не касаясь самих данных.
Ответ такой: мы храним постоянные данные в томах, которые по своей природе отсоединены от самого жизненного цикла контейнеров. Даже если мы удаляем некий контейнер с каким- то подключённым томом, сам том продолжит существовать независимо, сохраняя в безопасности наши данные. Затем мы можем воссоздать этот контейнер, подцепить этот том и всё шито- крыто.
Docker позволяет нам создавать несколько различных видов томов, каждый из которых выполняет собственное задание. Например, мы уже видели как смонтировать некий локальный том. Однако существует и другой вид тома, который лучше отвечает нашей цели. На самом деле нас не заботит где или как хранятся наши файлы, нас беспокоит лишь то, что они хранятся где- то отдельно. Для этого мы можем создать некий именованный том : автономную корзину (bucket) файлового хранилища, полностью управляемую Docker.
Но хватит теории; давайте посмотрим как это делать практически.
Именованные тома могут создаваться и управляться посредством соответствующей команды docker volume . Хотя об этом и стоит знать, раз уж мы применяем Compose, мы можем ему позволить обрабатывать всё необходимое управление такими томами за нас.
Вот наш docker-compose.yml изменённый для хранения наших постоянных данных в неком томе:
1: version: '3' - - services: - 5: web: - build: . - ports: - - "3000:3000" - volumes: 10: - .:/usr/src/app - env_file: - - .env/development/database - - .env/development/web - 15: redis: - image: redis - - database: - image: postgres 20: env_file: - - .env/development/database - volumes: - - db_data:/var/lib/postgresql/data - 25: volumes: - db_data:
Самый первый шаг состоит в том чтобы сообщить Compose что нам требуется некий именованный том. Именованные тома определяются под имеющимся свойством верхнего уровня volumes (строка 25); здесь мы определили некий именованный том с названием db_data (строка 26).
Затем нам требуется сообщить Compose о необходимости монтирования этого именованного тома внутри своего контейнера базы данных с применением уже знакомого нам свойства volumes (строка 22). Монтирование некого именованного тома аналогично монтированию какого- то локального каталога (строка 10) - единственное отличие в том, что та часть, которая расположена до имеющейся точки ссылается на само название такого именованного тома вместо локального пути. Здесь (строка 23) мы сообщаем, "Смонтируй наш именованный том db_data в /var/lib/postgresql/data " - том каталоге, в котором наш образ Postgres хранит свои файлы базы данных которые мы желаем видеть постоянными.
Хорошо, давайте раскрутим это. Мы уже изменили определение своего Compose для нашей службы database , поэтому нам потребуется перезапустить его. Однако, опять же, поскольку Compose повторно использует тот же самый контейнер для некоторой службы пока мы не попросим его о чём- то ином, нам придётся в явном виде сообщать Compose о необходимости создавать заново этот контейнер database чтобы прихватывать настройки своего нового тома.
Вначале остановим свою службу database :
$ docker-compose stop database
Затем давайте явным образом удалим её контейнер:
$ docker-compose rm -f database
Compose не запросит у нас подтверждения перед удалением этого контейнера - параметр принудительного исполнения -f (force) сообщает о необходимости двигаться далее и выполнить это.
Хорошо, самое время вернуть нашу базу данных обратно:
$ docker-compose up -d database Creating volume "myapp_db_data" with default driver Creating myapp_database_1 . done
Так как наш новый том теперь смонтирован в данном контейнере, мы стёрли все предыдущие базы данных и хранимые данные, следовательно нам требуется воссоздать необходимые базы данных и выполнить миграцию.
Давайте сделаем это сейчас:
$ docker-compose exec web bin/rails db:create db:migrate Database 'myapp_development' already exists Created database 'myapp_test' == 20190115100954 CreateUsers: migrating =================================== -- create_table(:users) ->> 0.0127s == 20190115100954 CreateUsers: migrated (0.0143s) ==========================
Замечательно, теперь давайте убедимся что наше приложение всё ещё работает. Посетим в своём браузере http://localhost:3000/users и убедимся что нам видны строительные подпорки нашего User . Великолепно - наш том представляется работающим.
Давайте докажем что наши данные теперь остаются постоянно даже когда мы удаляем их контейнер базы данных. Прежде всего нам требуется запомнить некие данные: добавим одного или более пользователей через подмостки Rails. на следующем рисунке я создал для себя некого отдельного пользователя:
Рисунок 6-3
Теперь когда у нас имеются некие сохранённые данные, давайте остановим свой контейнер базы данных:
$ docker-compose stop database Stopping myapp_database_1 . done
а затем и удалим его (вам потребуется выдать подтверждение после получения запроса):
$ docker-compose rm database Going to remove myapp_database_1 Are you sure? [yN] y Removing myapp_database_1 . done
Затем мы воссоздадим его и запустим его через:
$ docker-compose up -d database
Если это работает, мы должны увидеть данные своего пользователя, в точности как это было до того как мы удалили свой контейнер базы данных. Перезагрузите свой браузер ( http://localhost:3000/users ) и . наши данные всё ещё здесь. Ура!
Мы сказали что Docker управляет некой областью файловой системы для именованных томов, но где она расположена в действительности? Мы можем обнаружить где расположен наш именованный том db_data (который снабжён со стороны Compose префиксом папки нашего приложения и превращён в myapp_db_data ), исполнив:
$ docker volume inspect --format '>' myapp_db_data /var/lib/docker/volumes/myapp_db_data/_data
Как мы можем видеть, именованные тома хранятся в /var/lib/docker/volumes/ . А именно: в Linux это будет некий путь в вашей локальной файловой системе, но в macOS или Windows это ссылка на значение пути внутри соответствующей ВМ Dockerhost.
Беглый обзор
В этой главе мы изучили как устанавливать и настраивать некую базу данных для своего приложения Rails - то что требуется для большинства приложений Rails.
Давайте повторим то что мы прошли:
- При помощи Compose мы запустили некий сервер Postgres в контейнере.
- Мы убедились что наш сервер Postgres был запущен подключившись с помощью клиента Postgres из некого отдельного контейнера.
- Мы настроили своё приложение Rails на общение с Postgres установив требующийся gem Postgres, изменив свой файл database.yml и запустив соответствующую задачу Rake для создания требуемой базы данных.
- Мы продвинули свою новую базу данных, создав подмостки, выполнив миграции а также вставки, удаления и обновления записей.
- Мы обсудили почему будет хорошей мыслью отделить наши контейнеры базы данных от сам их данных, которые мы хотим видеть постоянными.
- Наконец, мы воспользовались именованным томом для хранения своих данных обособленно, позволяя нам управлять их жизненным циклом независимо от самого контейнера.
Теперь нам уже известно как добавлять две службы: Redis и Postgres. Вы должны быть способны применять те же самые знания для добавления прочих служб, о которых вы можете помышлять. < Прим. пер.: например, взамен Potgres поставить MS SQL Server, ха! > На самом деле в своей следующей главе мы добавим ещё одну службу, когда отвлечёмся от внутренних технологий чтобы изучить как внедрять современный интерфейс для вашего приложения Rails.
Установка и настройка PostgreSQL в Docker
Эта инструкция — часть курса «PostgreSQL для новичков».
Смотреть весь курс

Docker — удобный инструмент для создания изолированных сред. Именно этой своей особенностью он и удобен для разворачивания различных приложений, требующих дополнительных зависимостей.
В прошлой статье о Docker-контейнерах мы рассказывали о преимуществах контейнеризации в целом, а в этой рассмотрим их относительно СУБД PostgreSQL. Также расскажем о ее установке внутри контейнера.
Зачем использовать PostgreSQL в контейнере
Чтобы больше понять о преимуществах контейнеризации PostgreSQL, немного забежим вперед и для примера посмотрим на те зависимые пакеты, которые автоматически будут установлены вместе с приложениями, относящимся непосредственно к PostgreSQL, если мы будем ставить СУБД на сервер:
sudo apt install postgresql postgresql-contrib
Reading package lists. Done Building dependency tree Reading state information. Done The following additional packages will be installed: libllvm10 libpq5 libxslt1.1 postgresql-12 postgresql-client-12 postgresql-client-common postgresql-common Suggested packages: postgresql-doc postgresql-doc-12 libjson-perl Recommended packages: sysstat
В нашем примере их три: libllvm10, libpq5, libxslt1.1. В зависимости от дистрибутива их может быть больше. Посмотрим, от каких пакетов на самом деле зависит пакет postgresql-12 (спойлер: 25 обязательных пакетов и 1 рекомендованный):
sudo apt-cache depends postgresql-12
postgresql-12 |Depends: locales Depends: locales-all Depends: postgresql-client-12 Depends: postgresql-common Depends: ssl-cert Depends: tzdata |Depends: debconf Depends: cdebconf debconf Depends: libc6 Depends: libgcc-s1 Depends: libgssapi-krb5-2 Depends: libicu66 Depends: libldap-2.4-2 Depends: libllvm10 Depends: libpam0g Depends: libpq5 Depends: libselinux1 Depends: libssl1.1 Depends: libstdc++6 Depends: libsystemd0 Depends: libuuid1 Depends: libxml2 Depends: libxslt1.1 Depends: zlib1g Recommends: sysstat
Наличие или отсутствие тех или иных пакетов, различные версии и другие факторы напрямую влияют на стабильность работы PostgreSQL. Используя контейнеризацию, возможные конфликты несовместимости нивелируются, т.к. все необходимые зависимости уже будут находиться в среде контейнера. Если загрузить готовый образ контейнера с ресурса Docker Hub (об этом ниже в статье), мы получим протестированную на совместимость и полностью готовую к работе среду.
Еще одно важное преимущество использования контейнеризации среды PostgreSQL — воспроизводимость. Разработчики и те, кто вносит какие-либо изменения в код процедур или добавляет новый функционал, могут быстро развернуть тестовую среду, полностью идентичную боевой, чтобы проверить свои гипотезы.
И наконец, отказоустойчивость. Если с сервером что-то случится, точно такой же контейнер может быть запущен на другом сервере с уже примонтированным хранилищем датафайлов.
Откроем панель управления Selectel, перейдем в представление Облачная платформа и нажмем на кнопку Создать сервер.

Далее вводим имя сервера, выбираем образ операционной системы (остановимся на Ubuntu 20.04 LTS 64-bit) и фиксированную конфигурацию сервера с 2 vCPU и 4 ГБ RAM. Объем дискового пространства диска установим в 20 ГБ. Еще раз проверяем конфигурацию сервера и нажимаем Создать.

Проверим сетевые настройки, копируем пароль для root и удостоверимся в нижней части экрана, что все настройки корректны. Нажмем кнопку Создать.

Подождем минуту или две пока сервер не перейдет в состояние Active.

Теперь можем приступать к установке PostgreSQL в Docker. Поехали!
Как установить PostgreSQL в Docker из образа
Перед началом работы с PostgreSQL в контейнере Docker, установим сам Docker. Предварительно, добавим ключ для работы с репозиторием Docker Hub:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
Добавим этот репозиторий в локальный список репозиториев и установим Docker:
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt install docker-ce
Запустим демон Docker и активируем его автозапуск:
sudo systemctl start docker
sudo systemctl enable docker
Поскольку за пределами жизненного цикла контейнера не остается каких либо данных, на файловой системе сервера (или другом файловом хранилище) необходимо создать каталог для хранения данных, которые будут появятся в процессе работы экземпляра PostgreSQL.
mkdir -p $HOME/docker/volumes/postgres
Чтобы получить из репозитория Docker Hub готовый образ контейнера с PostgreSQL, выполним следующую команду:
sudo docker pull postgres
Using default tag: latest latest: Pulling from library/postgres f7ec5a41d630: Pull complete d073cd070242: Pull complete 03790957a916: Pull complete b3776ac15dab: Pull complete 7144fd00aec4: Pull complete 54f6491bd120: Pull complete 247ab23c6036: Pull complete 57800498c536: Pull complete bcb15a4d14f4: Pull complete cfc751ecbc6e: Pull complete bbf042afd4a4: Pull complete 453056a20de6: Pull complete d5b1a75378ef: Pull complete 7841e2074775: Pull complete Digest: sha256:61d5d8ef6cb4e2035f053f26b6b455c201a809354084cc8426b6904b8dd35602 Status: Downloaded newer image for postgres:latest docker.io/library/postgres:latest
Теперь все готово к запуску.
Как запустить контейнер PostgreSQL
Выполним команду docker с ключом run:
sudo docker run --rm --name selectel-pgdocker -e POSTGRES_PASSWORD=selectel -e POSTGRES_USER=selectel -e POSTGRES_DB=selectel -d -p 5432:5432 -v $HOME/docker/volumes/postgres:/var/lib/postgresql/data postgres
Если возникла ошибка вида: «Error starting userland proxy: listen tcp4 0.0.0.0:5432: bind: address already in use.», то следует вначале посмотреть какой процесс задействует порт 5432:
sudo ss -lptn 'sport = :5432'
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process LISTEN 0 244 127.0.0.1:5432 0.0.0.0:* users:(("postgres",pid=2592,fd=3)
Затем прибить” процесс по его PID и вновь выполнить запуск Docker-контейнера:
sudo kill 2592
Разберем ключи, которые мы использовали для запуска контейнера:
- —rm — ключ активирует автоматическое удаление контейнера и связанную с ним файловую систему после остановки контейнера. Полезный ключ для экономии дискового пространства.
- —name — ключ устанавливает имя контейнера. В пределах одного сервера имена контейнеров должны быть уникальны. Даже если один из них остановлен.
- -e — ключ задает переменные окружения, с которыми будет запущен контейнер. В нашей ситуации мы добавляем пароль суперпользователя, (POSTGRES_PASSWORD=selectel), имя суперпользователя (POSTGRES_USER=selectel) и имя базы данных по умолчанию (POSTGRES_DB=selectel) к базе данных.
- -d — ключ указывает, что контейнер должен быть запущен в в фоновом режиме (возвращает управление после его запуска).
- -p — ключ указывает на привязку внутреннего порта контейнера к порту сервера (используем порт по умолчанию 5432).
- -v — ключ создает точку монтирования каталога $HOME/docker/volumes/postgres на сервере к каталогу /var/lib/postgresql/data внутри контейнера.
Как подключиться к PostgreSQL в контейнере
После успешного запуска контейнера с PostgreSQL, попробуем к нему подключиться при помощи утилиты psql. Установим ее из пакета postgresql-client:
sudo apt install postgresql-client
Теперь можно подключиться и выполнить тестовый SQL-запрос:
psql -h 127.0.0.1 -U selectel -d selectel
Password for user selectel: psql (12.6 (Ubuntu 12.6-0ubuntu0.20.04.1), server 13.2 (Debian 13.2-1.pgdg100+1)) WARNING: psql major version 12, server major version 13. Some psql features might not work. Type "help" for help. selectel=#
Если появилось приглашение к вводу запроса, значит все действия были выполнены правильно.
Еще один вариант подключиться к базе данных, не устанавливая дополнительных утилит — подключиться непосредственно к Docker-контейнеру. Для этого выполним команду docker exec с дополнительными ключами:
sudo docker exec -it selectel-pgdocker psql -U selectel
psql (13.2 (Debian 13.2-1.pgdg100+1)) Type "help" for help. selectel=#
Приглашение к вводу запроса будет означать корректность ввода команды. Разберем ключи, которые мы использовали для выполнения команды:
- -i — ключ активирует интерактивную работу с терминалом.
- -t — ключ запускает псевдо-терминал (pseudo-TTY).
- selectel-pgdocker — имя контейнера, к которому выполняется подключение.
- psql — указание на запуск утилиты для подключение к базе данных PostgreSQL.
- -U — ключ указывает на имя пользователя, которое будет использоваться для подключения к базе данных.
Теперь попробуем создать новую таблицу, добавить в нее данные и выполнить запрос:
selectel=# create table cities (name varchar(80));
CREATE TABLE
selectel=# insert into cities values ('Moscow');
INSERT 0 1
selectel=# select * from cities;
name -------- Moscow (1 row)
Чтобы остановить запущенный контейнер выполним docker stop и укажем имя контейнера:
sudo docker stop selectel-pgdocker
Файлы и процессы, созданные контейнером, принадлежат пользователю postgres, который является внутренним по отношению к контейнеру. В отсутствие пространства имен пользователей внутри контейнера, UID и GID в контейнере могут иметь произвольное значение. На самом сервере этим UID и GID могут соответствовать привилегированные пользователи или группы соответственно.
Например, пользователь на хосте с тем же UID или GID, что и пользователь postgres в контейнере, сможет получить доступ к данным в различных каталогах хоста, а также сможет завершить любой запущенный процесс. Чтобы избежать такой бреши в безопасности, укажем при запуске контейнера специализированные переменные USERMAP_UID и USERMAP_GID:
sudo docker run --rm --name selectel-pgdocker -e POSTGRES_PASSWORD=selectel -e POSTGRES_USER=selectel -e POSTGRES_DB=selectel -e USERMAP_UID=999 -e USERMAP_GID=999 -d -p 5432:5432 -v $HOME/docker/volumes/postgres:/var/lib/postgresql/data postgres
Как запустить PostgreSQL в контейнере в составе docker-compose
Еще одним вариантом запуска PostgreSQL в Docker-контейнере, является запуск контейнера с базой данных в составе docker-compose. В первую очередь, создадим соответствующий yml-файл:
nano docker-compose.yml
version: '3.1' volumes: pg_selectel: services: pg_db: image: postgres restart: always environment: - POSTGRES_PASSWORD=selectel - POSTGRES_USER=selectel - POSTGRES_DB=selectel volumes: - pg_project:/var/lib/postgresql/data ports: - $:5432
Затем установим docker-compose:
sudo apt install docker-compose
Теперь запустим контейнер:
sudo docker-compose up -d
Ключ -d указывает, что docker-compose должен быть запущен в в фоновом режиме (вернет управление после его запуска).
Проверим возможность подключения к базе данных:
psql -h 192.168.0.4 -U selectel -d selectel
Password for user selectel: psql (12.6 (Ubuntu 12.6-0ubuntu0.20.04.1), server 13.2 (Debian 13.2-1.pgdg100+1)) WARNING: psql major version 12, server major version 13. Some psql features might not work. Type "help" for help. selectel=#
Появление приглашения к вводу команд для PostgreSQL означает корректность выполненных настроек.
Чтобы остановить запущенный контейнер, выполним docker-compose stop:
sudo docker-compose stop
Заключение
Мы рассказали о работе с базой данных PostgreSQL в контейнере Docker, запуске, выполнении запросов и остановке. Как и говорили в начале статьи, работа с контейнеризованной в Docker базой данных упрощает процесс разработки и администрирование. Контейнеры могут быть легко перезапущены на другом сервере и сервис, предоставляемый базой данных, не прервется.
Резервное копирование и восстановление PostgreSQL: pg_dump, pg_restore, wal-g
Установка пулера соединений PgBouncer для PostgreSQL
Зарегистрируйтесь в панели управления
И уже через пару минут сможете арендовать сервер, развернуть базы данных или обеспечить быструю доставку контента.