Локальный сеанс PG в не очень локальном контейнере

Раскрутить контейнер Docker — довольно простая задача. Вы берете изображение, запускаете несколько команд, и через несколько минут вся среда оказывается у вас под рукой. Что происходит, когда все должно стать немного сложнее?

А настойчивость? Открытие портов? Делитесь ресурсами?

Если вы создаете сложную базу данных с множеством служб, подключающихся к контейнеру Postgres, это может быстро привести к беспорядку, если вы не будете осторожны. Управление конфигурацией Postgres и пресловутым файлом pg_hba — рутинная работа, но есть более простой способ.

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

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

Предпосылки

В этом руководстве предполагается, что у вас уже есть настройки Docker и Docker Compose на родительском хост-компьютере, который вы будете использовать. Если вы еще этого не сделали, перейдите по ссылкам ниже:

Вам также нужно будет выделить некоторое пространство для сохранения тома. Сначала вам не понадобится много, но если вы собираетесь хранить данные базы данных на хосте, вам нужно выбрать путь и размер, соответствующие предполагаемому использованию.

Как только Docker будет готов к работе на хосте, мы можем приступить к созданию файла Compose.

Файл компоновки Docker

В этом примере мы будем использовать файл docker-compose.yml. Это позволит нам одновременно запускать множество разных контейнеров из одного файла. В этом файле у нас будет две службы. Первым будет Postgres, а вторым будет наше тестовое приложение, требующее доступа к локальной базе данных:

Давайте разберем, что происходит в этом файле:

  • У нас есть два сервиса (контейнера), первый — это наша база данных Postgres, а второй — наше «приложение». Вторая — это просто еще одна база данных Postgres, которая будет использовать psql для подключения к первой базе данных.
  • Мы передаем сокет Unix из первого Postgres во второй, разделяя том с обоими контейнерами. Этот сокет обычно находится в /var/run/postgresql.
  • В нашем втором сервисе «приложение» мы используем старый образ Postgres и модифицируем точку входа, чтобы она использовала psql для подключения к базе данных и запускала оператор SELECT для отображения информации о версии.
  • Версия Postgres отличается в службе приложение, чтобы проиллюстрировать, как она определенно подключается к первому экземпляру Postgres, а не локально в том же контейнере. В реальном производственном приложении вы просто используете адаптер базы данных или какую-то библиотеку ORM и указываете ее на сокет.
  • Мы также меняем пользователя второй службы «приложения» на использование postgres вместо root, чтобы нам не приходилось изменять какие-либо разрешения для сокета или роли в базе данных. Рабочее приложение должно использовать пользователя с соответствующей областью действия и соответствующими разрешениями.

Собираем все вместе

Теперь пришло время запустить наш файл Docker Compose и посмотреть результаты. Просто введите следующую команду в том же каталоге, что и файл docker-compose.yml, чтобы запустить всю композицию:

docker-compose up --build

После завершения сборки вы должны увидеть следующий вывод:

Здесь мы видим, что наша база данных запускается, наше приложение подключается и SELECT выполняется успешно. Обратите внимание, что выходные данные приложения показывают версию Postgres 14, а не 12, которая является версией, установленной в контейнере приложения. Это означает, что мы подключились к сокету, смонтированному в контейнере с хоста.

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

docker-compose up --build --force-recreate

Последние мысли

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

Этот метод позволяет избежать ситуаций, когда вы имеете дело с устаревшим приложением, которое трудно поместить в контейнер из-за его жесткой зависимости от локальной базы данных. Хотя большинство современных приложений, работающих с базой данных, должны поддерживать подключение к удаленной базе данных, бывают случаи, когда вам может понадобиться подключиться с помощью сокета.

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

Спасибо за прочтение! Если вам понравилась эта статья, пожалуйста, ознакомьтесь с несколькими другими моими постами ниже: