#1224: Как настроить репликацию БД Swarmica?

Симптомы

Можно ли настроить репликацию базы Swarmica для аналитики или резервного копирования?

Решение

Да, Swarmica использует Postgres в качестве СУБД, который поддерживает репликацию.

Чтобы включить репликацию, необходимо выполнить шаги на основном сервере и на реплике, описанные ниже.

Настройка основного сервера Swarmica

1. Создайте файл /root/swarmica/pg_hba.conf со следующим содержимым (замените REPLICA_IP на IP адрес сервера реплики):

local   all             all                                     trust
host    all             all             127.0.0.1/32            trust
host    all             all             ::1/128                 trust
local   replication     all                                     trust
host    replication     all             127.0.0.1/32            trust
host    replication     all             ::1/128                 trust
host    replication     all             REPLICA_IP/32           scram-sha-256
host all all all scram-sha-256

2. Отредактируйте /root/swarmica/docker-compose.yml, добавив монтирование pg_hba.conf в раздел volumes и передав необходимые настройки сервера postgres через команды -c:

postgres:
  image: postgres:14.2-bullseye
  container_name: swarmica-postgres
  shm_size: 8gb
  command: postgres -N 300 -c shared_preload_libraries=pg_stat_statements -c pg_stat_statements.track=all -c wal_keep_size=512MB -c work_mem=8MB -c temp_buffers=16MB -c shared_buffers=8GB -c track_activity_query_size=16384 -c max_wal_size=4GB -c checkpoint_timeout=10min
  restart: always
  volumes:
    - swarmica_postgres_data:/var/lib/postgresql/data:Z
    - swarmica_postgres_data_backups:/backups:z
    - ./pg_hba.conf:/var/lib/postgresql/data/pg_hba.conf
  env_file:
    - .env
  ports:
    - "54321:5432"

ВНИМАНИЕ! Для репликации на другом сервере необходимо сделать порт 5432 контейнера postgres доступным на сервере. Это повышает уязвимость сервера к внешним атакам, поэтому рекомендуется принять все возможные меры защиты, такие как:

  • Изменение адреса порта (в примере выше - 54321)
  • Ограничение доступа к порту средствами файрвола на сервере
  • Ограничение доступа к порту средствами внешнего файрвола / NATа / WAF / NGFW

3. Перезагрузите сервисы:

cd /root/swarmica
docker compose down
docker compose up -d

4. Разрешите репликацию для учетной записи, которую будете использовать на реплике:

docker exec -it swarmica-postgres psql -U ... ...
CREATE USER replicator WITH REPLICATION ENCRYPTED PASSWORD 'replicator_insecure_password';
SELECT pg_create_physical_replication_slot('replication_slot');

ВНИМАНИЕ! Обязательно замените replicator и replicator_insecure_password на собственные, более защищенные имя пользователя и пароль

Настройка реплики

Здесь приводится пример настройки реплики внутри Docker контейнера на другом физическом/виртуальном сервере, вы можете применять аналогичные настройки в любом варианте установки Postgres.

1. Установите docker.io и docker-compose-v2 пакеты:

apt-get update
apt-get install docker.io docker-compose-v2

2. Создайте папку для конфигурационных файлов:

mkdir replica
cd replica

3. Создайте .env файл с параметрами подключения Postgres:

# Master host connection configuration
POSTGRES_MASTER_HOST=my-swarmica-host.tld
POSTGRES_MASTER_PORT=54321
POSTGRES_MASTER_DB=swarmica_app
POSTGRES_MASTER_USER=replicator
POSTGRES_MASTER_PASSWORD=replicator_insecure_password

# Replica host configuration
POSTGRES_HOST=postgres
POSTGRES_USER=replicator
POSTGRES_PASS=repplicator_insecure_password
POSTGRES_PORT=5432

4. Создайте docker-compose.yml файл со следующим содержимым:

volumes:
  postgres_data: {}

services:
  postgres:
    image: postgres:14.2-bullseye
    restart: always
    container_name: swarmica-postgres
    shm_size: 1gb
    environment:
      PGPASSWORD: $POSTGRES_MASTER_PASSWORD
    command: |
      gosu postgres bash -c "
      if [ ! -s /var/lib/postgresql/data/postgresql.conf ]; then
        pg_basebackup -h $POSTGRES_MASTER_HOST -p $POSTGRES_MASTER_PORT -U $POSTGRES_MASTER_USER -D /var/lib/postgresql/data -R -v --slot=replication_slot;
      fi
      chmod 700 /var/lib/postgresql/data/
      postgres -N 1024 -c hot_standby=on
      "
    volumes:
      - postgres_data:/var/lib/postgresql/data:Z
    env_file:
      - .env

5. Скачайте образы и запустите сервис реплики:

docker compose pull
docker compose up -d

6. После этого репликация дожна начаться автоматически:

root@pg-replica:~/replica# docker logs -f swarmica-postgres
pg_basebackup: initiating base backup, waiting for checkpoint to complete
pg_basebackup: checkpoint completed
pg_basebackup: write-ahead log start point: 20/22000028 on timeline 1
pg_basebackup: starting background WAL receiver
pg_basebackup: write-ahead log end point: 20/22000B88
pg_basebackup: waiting for background process to finish streaming ...
pg_basebackup: syncing data to disk ...
pg_basebackup: renaming backup_manifest.tmp to backup_manifest
pg_basebackup: base backup completed
2025-12-11 12:54:07.181 UTC [1] LOG:  starting PostgreSQL 14.2 (Debian 14.2-1.pgdg110+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit
2025-12-11 12:54:07.181 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
2025-12-11 12:54:07.181 UTC [1] LOG:  listening on IPv6 address "::", port 5432
2025-12-11 12:54:07.191 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2025-12-11 12:54:07.201 UTC [14] LOG:  database system was interrupted; last known up at 2025-12-11 12:53:56 UTC
2025-12-11 12:54:07.461 UTC [14] LOG:  entering standby mode
2025-12-11 12:54:07.468 UTC [14] LOG:  redo starts at 20/22000028
2025-12-11 12:54:07.471 UTC [14] LOG:  consistent recovery state reached at 20/22000B88
2025-12-11 12:54:07.472 UTC [1] LOG:  database system is ready to accept read-only connections
2025-12-11 12:54:07.798 UTC [18] LOG:  started streaming WAL from primary at 20/23000000 on timeline 1