Это конспект, который представляет собой личные заметки по решению указанной задачи. Цель задачи: расшарить локальную БД для единовременного доступа с нескольких клиентов. При решении был использован дешевый VPS от известного хостера.
Ред.: как указали в комментариях, решение небезопасное, т.к. предполагает доступ к СУБД через открытый порт, и не подходит для больших БД, т.к. требует места для промежуточного хранения дампов памяти.

Вводные

Предполагается, что на локальном хосте уже установлен Docker и запущен контейнер с нужной версией PostgresQL, где инициализирована база данных, которая и является целью для трансфера. Синхронизация локальной и удаленной БД в дальнейшем не предусмотрена.

На всякий случай привожу ключевые параметры моей системы на момент выполнения работы:

Скрытый текст
  • ОС: macOS Monterey 12.6.1

  • Docker локальный: 24.0.7, build afdd53b

  • Docker на VPS: 20.10.5+dfsg1, build 55c4c88

  • PostgresQL образ: postgres:16

  • pgAdmin образ: dpage/pgadmin4:7.7

VPS:

  • Virtualization: microsoft

  • Operating System: Debian GNU/Linux 11 (bullseye)         

  • Kernel: Linux 5.10.0-11-amd64

  • Architecture: x86-64

Смотрим запущеные контейнеры:

docker ps

Запускаем терминал внутри нужного контейнера:

docker exec -it myPostgreSQL_1 bash 

Создаём дамп нужной БД (подставьте своё название вместо beads):

 pg_dump -U postgres beads > /tmp/beads.sql 

Теперь внутри контейнера на локальном хосте сохранена Ваша БД в папке /tmp/

Не забываем вернуться из bash'a докера:

 exit 

Копируем полученный дамп из контейнера на локальный хост в папку /tmp/:

 docker cp myPostgreSQL_1:/tmp/beads.sql /tmp/ 

Теперь можно увидеть Ваш дамп в прописанной папке на локальном хосте.

Получение VPS

Наверняка, RUVDS – не самый оптимальный вариант, но на данном этапе для обучения этот сервис меня устраивает. Я выбрал у них дешман-машину самый простой вариант, которой по бесконечной акции всегда стоит около 100 руб.

Скрытый текст

Нажимаем "VPS Старт":

В верхнем левом углу сайта выпадающее меню.
В верхнем левом углу сайта выпадающее меню.

Далее можно выбрать физическое расположение сервера (вероятно, что это так). На всякий случай проговорю, что я выбрал "Москва M9":

Выбор дата-центра
Выбор дата-центра

Есть выбор ОС. Далее я использую Debian:

Вид заказа
Вид заказа

В личном кабинете получаем IP для доступа к пустой машине:

Личный кабинет
Личный кабинет

Продублирую, что выводит команда hostnamectl на полученном сервере:

Скрытый текст
  • Virtualization: microsoft

  • Operating System: Debian GNU/Linux 11 (bullseye)         

  • Kernel: Linux 5.10.0-11-amd64

  • Architecture: x86-64

Работа с VPS

На сервере предустановлен SSH. Поэтому дальнейшее общение с сервером будет проходить именно по этому протоколу. Подключаемся:

ssh <имя пользователя>@<ip Вашего VPS>

"Из коробки" надо подключаться с именем root и паролем, который дают Вам в личном кабинете, но по некоторым соображениям безопасности надо добавлять нового пользователя и совсем отключать возможность входить с именем root. Однако с этим можно разобраться когда Ваш VPS начнем майнить позднее.

После подключения можно посмотреть, что ещё предустановлено:

dpkg-query -l

Создаем папку на сервере для временного переноса ранее подготовленного дампа:

mkdir tmp

Получается что-то вроде /home/roman/tmp.

Переходим в терминал локального хоста.

Переносим дамп с локального хоста на сервер:

 scp /tmp/beads.sql roman@194.87.93.164:/home/roman/tmp

Переходим в терминал VPS.

Устанавливаем докер на сервер (я делал по вот этому туториалу):

sudo apt update -y
sudo apt upgrade -y
sudo apt install -y docker.io
sudo systemctl start docker

Подтягиваем и запускаем пустой контейнер с PostgresQL:

sudo docker pull postgres:16
docker run -d \
-p 5432:5432 \
--restart always\
--name myPostgreSQL \
--mount type=bind,source="/home/roman/bd",target="/var/lib/postgresql/data" \
-e POSTGRES_USER=<ВАШЕ ИМЯ ПОЛЬЗОВАТЕЛЯ> \
-e POSTGRES_PASSWORD=<ВАШ ПАРОЛЬ ОТ ЭТОГО ПОЛЬЗОВАТЕЛЯ> \
postgres:16

Переносим дамп БД внутрь контейнера на сервере:

sudo docker cp ~/tmp/beads.sql myPostgreSQL:/tmp/

здесь myPostgreSQL - это моё название контейнера. Конкретное название запущенного контейнера всегда можно проверить командой выше docker ps.

Запустить psql внутри контейнера:

 sudo docker exec -it myPostgreSQL psql -U postgres

Внутри psql импортировать БД:

 \i /tmp/beads.sql

Раз у нас целых 10 Гб ПЗУ на сервере, то можно также поставить pgadmin прямо на сервер:

sudo docker pull dpage/pgadmin4:7.7
docker run -d\
 -p 5050:80 \
 --name myPGAdmin \
 -e "PGADMIN_DEFAULT_EMAIL=<ВАШ email>" \
 -e "PGADMIN_DEFAULT_PASSWORD=<ВАШ ПАРОЛЬ>" \
 dpage/pgadmin4:7.7

Теперь из любого pgadmin, имеющего доступ к интернету, можно добавить сервер:

подключение pgadmin к Вашей БД
подключение pgadmin к Вашей БД
Произвольное имя
Произвольное имя
Заполняем сведения
Заполняем сведения

Если всё ок, то в pgadmin уже можно смотреть БД.

Код на python'e так же подключается без заминок:

import psycopg2
from psycopg2 import Error
from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT

import configparser
config = configparser.ConfigParser()
config.read("config.ini")

class DB:
    def __init__(self):           
        try:
            # Подключение к существующей базе данных
            self.conn = psycopg2.connect(dbname = config['beads_db']['dbname'],
                                        user = config['beads_db']['user'],
                                        password = config['beads_db']['password'],
                                        host = config['beads_db']['host'],
                                        port = config['beads_db']['port'])
            print("соединение установлено")
            self.conn.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)
            # Курсор для выполнения операций с базой данных
            self.cur = self.conn.cursor()
            print("курсор создан")

        except (Exception, Error) as error:
            print("Ошибка при работе с PostgreSQL", error)

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


  1. fedorro
    03.09.2024 13:35
    +4

    docker run -d \-p 5432:5432 \--name myPostgreSQL \-e POSTGRES_USER=<ВАШЕ ИМЯ ПОЛЬЗОВАТЕЛЯ> \-e POSTGRES_PASSWORD=<ВАШ ПАРОЛЬ ОТ ЭТОГО ПОЛЬЗОВАТЕЛЯ> \postgres:16

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

    Ну и всё делается гораздо легче и быстрее:

    rsync -av /home/user/postgres_data new_server_ip:/home/user

    Копирует папку с данными и их атрибуты, остается только на new_server запустить образ с Postgres с примонтированными данными.

    А если БД большая - так и никого места не хватит, дамп, копия дампа в контейнере, данные из дампа...

    В итоге - сборник советов как делать не нужно.


    1. RomanBashmakov Автор
      03.09.2024 13:35

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


      1. fedorro
        03.09.2024 13:35

        Вариант 1: у Вас PGAdmin и Postgres на одной машине в свойствах подключения можно указать имя или IP контейнера в докерной сети, порт внутри доступен и без расшаривания во вне.

        Вариант 2: PGAdmin или любой другой клиент поддерживают подключение через ssh - видел абсолютно в любом клиенте. Тогда в подключении к ssh вбиваете данные от VPS, а в подключении к серверу localhost, тогда, возможно придется пробросить порт через -p, но только на локальный хост: -p127.0.0.1:5432:5432


        1. RomanBashmakov Автор
          03.09.2024 13:35

          Поправил запуск контейнера (добавил перезапуск и биндинг с внешней папкой) и добавил замечания к аннотации (надеюсь, больше никого не введу в заблуждение). Про безопасность тоже нам новичкам будет полезно. Спасибо!


  1. VenbergV
    03.09.2024 13:35

    Касательно ssh. Перейдите на ключи и отключите парольный доступ. Так жить будет уже спокойнее.