From 37f3a94994640186cdd8f9997acfa043c7da6ab4 Mon Sep 17 00:00:00 2001 From: Crimson Date: Wed, 25 Mar 2026 10:03:07 +0000 Subject: [PATCH] =?UTF-8?q?=D0=97=D0=B0=D0=B3=D1=80=D1=83=D0=B7=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20=D1=84=D0=B0=D0=B9=D0=BB=D1=8B=20=D0=B2=20=C2=AB?= =?UTF-8?q?/=C2=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 136 ++++++++++++++++++++ env | 19 +++ env.example | 102 +++++++++++++++ install_pg1c.sh | 326 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 583 insertions(+) create mode 100644 README.md create mode 100644 env create mode 100644 env.example create mode 100644 install_pg1c.sh diff --git a/README.md b/README.md new file mode 100644 index 0000000..a9d7499 --- /dev/null +++ b/README.md @@ -0,0 +1,136 @@ +# Установка PostgreSQL for 1C 18 на Debian 13 одним запуском + +В комплекте: +- `install_pg1c.sh` — основной установочный скрипт +- `env.example` — пример файла `.env` со всеми настройками и пояснениями на русском + +Скрипт автоматизирует официальный процесс установки Postgres Pro для 1С 18 по вашей инструкции: +- добавляет репозиторий через vendor-скрипт `pgpro-repo-add.sh` +- ставит пакет в режиме `standalone` или `parallel` +- включает и запускает systemd-сервис +- создает или обновляет пользователя PostgreSQL +- при необходимости создает базу данных +- при необходимости автоматически правит `pg_hba.conf`, чтобы логин работал по паролю, а не упирался в `peer` + +## Что нужно + +- Debian 13 +- доступ `root` +- интернет-доступ до репозитория Postgres Pro + +## Быстрый запуск + +```bash +cp env.example .env +nano .env +chmod +x install_pg1c.sh +sudo ./install_pg1c.sh +``` + +## Что настроить в `.env` + +Обязательно проверьте: +- `INSTALL_MODE` +- `PG_ADMIN_USER` +- `PG_ADMIN_PASSWORD` +- `PG_CREATE_DB` +- `PG_DB_NAME` +- `ENFORCE_PASSWORD_AUTH` + +## Режимы установки + +### 1) Если это единственный Postgres на сервере + +```env +INSTALL_MODE=standalone +``` + +Ставится пакет: +```text +postgrespro-1c-18 +``` + +### 2) Если на сервере уже есть другой Postgres + +```env +INSTALL_MODE=parallel +``` + +Ставится пакет: +```text +postgrespro-1c-18-contrib +``` + +После этого скрипт сам вызывает `initdb`, включает сервис и запускает его. + +## Про аутентификацию + +По умолчанию на Linux локальные подключения к PostgreSQL часто идут через `peer`, из-за чего пароль вроде бы задан, но вход под новым пользователем не работает через локальный сокет. + +Во второй версии скрипта это закрыто параметром: + +```env +ENFORCE_PASSWORD_AUTH=true +``` + +Тогда скрипт: +- определяет фактический путь к `pg_hba.conf` +- делает резервную копию +- заменяет `peer` / `ident` на нужный метод (`scram-sha-256` по умолчанию) +- перезапускает сервис + +Рекомендуемые значения: + +```env +REPLACE_LOCAL_PEER_WITH=scram-sha-256 +REPLACE_HOST_AUTH_WITH=scram-sha-256 +``` + +## Проверки после установки + +Статус сервиса: + +```bash +systemctl status postgrespro-1c-18 +``` + +Список ролей: + +```bash +sudo -u postgres /opt/pgpro/1c-18/bin/psql -h /var/run/postgresql -d postgres -c "\du" +``` + +Список баз: + +```bash +sudo -u postgres /opt/pgpro/1c-18/bin/psql -h /var/run/postgresql -d postgres -c "\l" +``` + +Подключение под созданным пользователем: + +```bash +/opt/pgpro/1c-18/bin/psql -h 127.0.0.1 -U admin_1c -d appdb -W +``` + +## Что делает скрипт безопасно + +Скрипт старается быть идемпотентным: +- если репозиторий уже добавлен, повторно не ломает конфигурацию +- если роль уже существует, обновляет пароль и атрибуты +- если база уже существует, повторно не создает ее +- перед правкой `pg_hba.conf` делает бэкап, если `CREATE_HBA_BACKUP=true` + +## Важно + +- Скрипт рассчитан именно на Debian 13. +- Он использует официальный vendor-скрипт добавления репозитория, а не “самодельную” схему репозиториев. +- Если доступ к репозиторию требует логин/пароль, это обрабатывает сам vendor-скрипт Postgres Pro. В текущей версии ссылки вынесены в `.env`, но учетные данные доступа к репозиторию не дублируются вручную без явной необходимости. + +## Рекомендуемый порядок файлов в проекте + +```text +install_pg1c.sh +env.example +.env +README.md +``` diff --git a/env b/env new file mode 100644 index 0000000..d16877f --- /dev/null +++ b/env @@ -0,0 +1,19 @@ +REPO_ADD_URL=https://repo.postgrespro.ru/1c/1c-18/keys/pgpro-repo-add.sh +REPO_ADD_TMP=/tmp/pgpro-repo-add.sh +PGPRO_BIN_DIR=/opt/pgpro/1c-18/bin +SERVICE_NAME=postgrespro-1c-18 +PACKAGE_STANDALONE=postgrespro-1c-18 +PACKAGE_PARALLEL=postgrespro-1c-18-contrib +POSTGRES_SOCKET_DIR=/var/run/postgresql +INSTALL_MODE=standalone +PG_ADMIN_USER=admin_1c +PG_ADMIN_PASSWORD=StrongPassword123! +PG_ADMIN_SUPERUSER=true +PG_CREATE_DB=true +PG_DB_NAME=appdb +PG_SERVICE_ENABLE=true +PG_SERVICE_START=true +ENFORCE_PASSWORD_AUTH=true +REPLACE_LOCAL_PEER_WITH=scram-sha-256 +REPLACE_HOST_AUTH_WITH=scram-sha-256 +CREATE_HBA_BACKUP=true diff --git a/env.example b/env.example new file mode 100644 index 0000000..4ba0bc8 --- /dev/null +++ b/env.example @@ -0,0 +1,102 @@ +# ============================== +# Пример файла окружения для install_pg1c.sh +# Скопируйте этот файл в .env и заполните значения под ваш сервер: +# cp env.example .env +# nano .env +# ============================== + +# ------------------------------ +# Ссылки и технические параметры установки +# ------------------------------ + +# Официальный shell-скрипт Postgres Pro для добавления репозитория 1С 18. +# Скрипт установки скачает и выполнит его автоматически. +REPO_ADD_URL=https://repo.postgrespro.ru/1c/1c-18/keys/pgpro-repo-add.sh + +# Временный путь, куда будет скачан vendor-скрипт. +REPO_ADD_TMP=/tmp/pgpro-repo-add.sh + +# Путь к бинарникам Postgres Pro 1C 18. +PGPRO_BIN_DIR=/opt/pgpro/1c-18/bin + +# Имя systemd-сервиса. +SERVICE_NAME=postgrespro-1c-18 + +# Имя пакета для случая, когда это единственный Postgres на сервере. +PACKAGE_STANDALONE=postgrespro-1c-18 + +# Имя пакета для случая, когда рядом уже есть другой Postgres. +PACKAGE_PARALLEL=postgrespro-1c-18-contrib + +# Сокет PostgreSQL. Обычно оставляйте как есть. +POSTGRES_SOCKET_DIR=/var/run/postgresql + +# ------------------------------ +# Режим установки +# ------------------------------ + +# standalone = если это единственный Postgres на машине +# parallel = если на сервере уже есть другой Postgres и он должен жить параллельно +INSTALL_MODE=standalone + +# ------------------------------ +# Создание администратора PostgreSQL +# ------------------------------ + +# Имя роли/пользователя PostgreSQL, которую создаст скрипт. +PG_ADMIN_USER=admin_1c + +# Пароль этой роли. +# Замените на свой сильный пароль. +PG_ADMIN_PASSWORD=StrongPassword123! + +# true = дать SUPERUSER +# false = создать обычную роль с LOGIN + CREATEDB + CREATEROLE +PG_ADMIN_SUPERUSER=true + +# ------------------------------ +# Создание базы данных +# ------------------------------ + +# true = создать отдельную базу данных +# false = не создавать базу, останется только роль +PG_CREATE_DB=true + +# Имя базы, которая будет создана при PG_CREATE_DB=true +PG_DB_NAME=appdb + +# ------------------------------ +# Управление сервисом +# ------------------------------ + +# true = включить автозапуск systemd-сервиса +# false = не включать автозапуск +PG_SERVICE_ENABLE=true + +# true = запускать/перезапускать сервис в конце установки +# false = не трогать запуск сервиса +PG_SERVICE_START=true + +# ------------------------------ +# Настройка аутентификации (pg_hba.conf) +# ------------------------------ + +# true = скрипт автоматически правит pg_hba.conf, +# чтобы локальные подключения не упирались в peer/ident, +# а использовали парольную аутентификацию. +# false = pg_hba.conf не меняется. +ENFORCE_PASSWORD_AUTH=true + +# Чем заменить local ... peer/ident +# Рекомендуемо: scram-sha-256 +# Допустимо: md5, password, trust +REPLACE_LOCAL_PEER_WITH=scram-sha-256 + +# Чем заменить host/hostssl/hostnossl правила +# Рекомендуемо: scram-sha-256 +# Допустимо: md5, password, trust +REPLACE_HOST_AUTH_WITH=scram-sha-256 + +# true = перед правкой pg_hba.conf сделать резервную копию +# false = не делать бэкап +CREATE_HBA_BACKUP=true diff --git a/install_pg1c.sh b/install_pg1c.sh new file mode 100644 index 0000000..e433aae --- /dev/null +++ b/install_pg1c.sh @@ -0,0 +1,326 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" +ENV_FILE="${ENV_FILE:-${SCRIPT_DIR}/.env}" + +log() { + printf '[%s] %s +' "$(date '+%F %T')" "$*" +} + +fail() { + printf 'ERROR: %s +' "$*" >&2 + exit 1 +} + +need_cmd() { + command -v "$1" >/dev/null 2>&1 || fail "Не найдена команда: $1" +} + +bool_norm() { + case "${1:-}" in + 1|true|TRUE|yes|YES|on|ON) echo "true" ;; + 0|false|FALSE|no|NO|off|OFF) echo "false" ;; + *) fail "Неверное булево значение: ${1:-}" ;; + esac +} + +require_root() { + [[ "$(id -u)" -eq 0 ]] || fail "Скрипт нужно запускать от root" +} + +load_env() { + [[ -f "$ENV_FILE" ]] || fail "Файл окружения не найден: $ENV_FILE" + + set -a + # shellcheck disable=SC1090 + . "$ENV_FILE" + set +a + + : "${REPO_ADD_URL:?В .env должна быть переменная REPO_ADD_URL}" + : "${PGPRO_BIN_DIR:?В .env должна быть переменная PGPRO_BIN_DIR}" + : "${SERVICE_NAME:?В .env должна быть переменная SERVICE_NAME}" + : "${PACKAGE_STANDALONE:?В .env должна быть переменная PACKAGE_STANDALONE}" + : "${PACKAGE_PARALLEL:?В .env должна быть переменная PACKAGE_PARALLEL}" + : "${PG_ADMIN_USER:?В .env должна быть переменная PG_ADMIN_USER}" + : "${PG_ADMIN_PASSWORD:?В .env должна быть переменная PG_ADMIN_PASSWORD}" + + INSTALL_MODE="${INSTALL_MODE:-standalone}" + PG_ADMIN_SUPERUSER="$(bool_norm "${PG_ADMIN_SUPERUSER:-true}")" + PG_CREATE_DB="$(bool_norm "${PG_CREATE_DB:-false}")" + PG_SERVICE_ENABLE="$(bool_norm "${PG_SERVICE_ENABLE:-true}")" + PG_SERVICE_START="$(bool_norm "${PG_SERVICE_START:-true}")" + ENFORCE_PASSWORD_AUTH="$(bool_norm "${ENFORCE_PASSWORD_AUTH:-true}")" + REPLACE_LOCAL_PEER_WITH="${REPLACE_LOCAL_PEER_WITH:-scram-sha-256}" + REPLACE_HOST_AUTH_WITH="${REPLACE_HOST_AUTH_WITH:-scram-sha-256}" + CREATE_HBA_BACKUP="$(bool_norm "${CREATE_HBA_BACKUP:-true}")" + POSTGRES_SOCKET_DIR="${POSTGRES_SOCKET_DIR:-/var/run/postgresql}" + PG_DB_NAME="${PG_DB_NAME:-}" + REPO_ADD_TMP="${REPO_ADD_TMP:-/tmp/pgpro-repo-add.sh}" + + case "$INSTALL_MODE" in + standalone|parallel) ;; + *) fail "INSTALL_MODE должен быть standalone или parallel" ;; + esac + + case "$REPLACE_LOCAL_PEER_WITH" in + scram-sha-256|md5|password|trust) ;; + *) fail "REPLACE_LOCAL_PEER_WITH должен быть scram-sha-256, md5, password или trust" ;; + esac + + case "$REPLACE_HOST_AUTH_WITH" in + scram-sha-256|md5|password|trust) ;; + *) fail "REPLACE_HOST_AUTH_WITH должен быть scram-sha-256, md5, password или trust" ;; + esac + + if [[ "$PG_CREATE_DB" == "true" && -z "$PG_DB_NAME" ]]; then + fail "Если PG_CREATE_DB=true, нужно указать PG_DB_NAME" + fi + + PSQL="${PGPRO_BIN_DIR}/psql" + PGSETUP="${PGPRO_BIN_DIR}/pg-setup" + PG_ISREADY="${PGPRO_BIN_DIR}/pg_isready" +} + +check_os() { + [[ -f /etc/os-release ]] || fail "Не найден /etc/os-release" + # shellcheck disable=SC1091 + . /etc/os-release + + [[ "${ID:-}" == "debian" ]] || fail "Скрипт рассчитан на Debian. Найдено: ${ID:-unknown}" + [[ "${VERSION_ID:-}" == "13" ]] || fail "Скрипт рассчитан на Debian 13. Найдено: ${VERSION_ID:-unknown}" +} + +ensure_base_packages() { + export DEBIAN_FRONTEND=noninteractive + apt-get update + apt-get install -y wget ca-certificates gnupg apt-transport-https sed grep coreutils +} + +ensure_repo() { + if [[ -f /etc/apt/sources.list.d/postgresql-1c-18.list ]]; then + log "Репозиторий PostgreSQL for 1C 18 уже добавлен" + apt-get update + return + fi + + log "Скачиваю vendor-скрипт добавления репозитория" + wget -O "$REPO_ADD_TMP" "$REPO_ADD_URL" + chmod +x "$REPO_ADD_TMP" + sh "$REPO_ADD_TMP" + rm -f "$REPO_ADD_TMP" +} + +install_pgpro() { + export DEBIAN_FRONTEND=noninteractive + + if [[ "$INSTALL_MODE" == "standalone" ]]; then + log "Устанавливаю пакет ${PACKAGE_STANDALONE}" + apt-get install -y "$PACKAGE_STANDALONE" + else + log "Устанавливаю пакет ${PACKAGE_PARALLEL} для параллельной установки" + apt-get install -y "$PACKAGE_PARALLEL" + [[ -x "$PGSETUP" ]] || fail "Не найден $PGSETUP" + + if [[ ! -d /var/lib/pgpro/1c-18/data/base ]]; then + log "Инициализирую новый кластер Postgres Pro 1C 18" + "$PGSETUP" initdb + else + log "Кластер уже инициализирован, initdb пропускаю" + fi + fi +} + +enable_and_start_service() { + if ! systemctl list-unit-files | grep -q "^${SERVICE_NAME}\.service"; then + fail "Не найден unit-файл ${SERVICE_NAME}.service" + fi + + if [[ "$PG_SERVICE_ENABLE" == "true" ]]; then + log "Включаю автозапуск ${SERVICE_NAME}" + systemctl enable "$SERVICE_NAME" + fi + + if [[ "$PG_SERVICE_START" == "true" ]]; then + log "Запускаю ${SERVICE_NAME}" + systemctl restart "$SERVICE_NAME" + fi +} + +wait_for_postgres() { + [[ -x "$PG_ISREADY" ]] || fail "Не найден $PG_ISREADY" + + log "Жду готовности PostgreSQL" + local i + for i in {1..30}; do + if runuser -u postgres -- "$PG_ISREADY" -h "$POSTGRES_SOCKET_DIR" -d postgres >/dev/null 2>&1; then + return 0 + fi + sleep 1 + done + + systemctl status "$SERVICE_NAME" --no-pager || true + fail "PostgreSQL не поднялся за ожидаемое время" +} + +psql_postgres() { + runuser -u postgres -- "$PSQL" -v ON_ERROR_STOP=1 -h "$POSTGRES_SOCKET_DIR" -d postgres "$@" +} + +configure_role() { + [[ -x "$PSQL" ]] || fail "Не найден $PSQL" + + log "Создаю или обновляю роль ${PG_ADMIN_USER}" + + local role_attr="LOGIN" + if [[ "$PG_ADMIN_SUPERUSER" == "true" ]]; then + role_attr+=" SUPERUSER" + else + role_attr+=" NOSUPERUSER CREATEDB CREATEROLE" + fi + + local safe_user safe_pass + safe_user="${PG_ADMIN_USER//'/''}" + safe_pass="${PG_ADMIN_PASSWORD//'/''}" + + psql_postgres < "$tmp_file" + + cat "$tmp_file" > "$hba_file" + rm -f "$tmp_file" + + log "Перезапускаю ${SERVICE_NAME} после правки pg_hba.conf" + systemctl restart "$SERVICE_NAME" + wait_for_postgres +} + +show_summary() { + local auth_mode_note + if [[ "$ENFORCE_PASSWORD_AUTH" == "true" ]]; then + auth_mode_note="да (${REPLACE_LOCAL_PEER_WITH} / ${REPLACE_HOST_AUTH_WITH})" + else + auth_mode_note="нет" + fi + + cat <