Base
Установка с использованием docker на Astra Linux
Полная документация к скрипту base.sh — Установка и настройка Questionnaire Studio Pro (QSPRO)
Общее описание системы
Данный Скрипт — это автоматизированный установщик для комплексного решения Questionnaire Studio Pro (QSPRO), в Debian-подобных системах, предназначенного для создания, запуска и анализа опросов и анкет.
Система включает:
Веб-приложение QSPRO (на .NET) — основной фронтенд и бэкенд
PostgreSQL — основная СУБД
PgBouncer — пуллер соединений к PostgreSQL
Caddy — обратный прокси-сервер
Memcached — общее key-value хранилище
Все компоненты запускаются через Docker и Docker Compose, что обеспечивает изоляцию, масштабируемость и переносимость.
Обновите систему и Установите базовые утилиты:
apt update && sudo apt upgrade -y
apt install -y curl wget gnupg2 software-properties-common apt-transport-https
Установите:
docker и docker-compose
apt install jq && apt install docker.io && apt install docker-compose
Минимальные требования к inotify:
fs.inotify.max_user_instances
fs.inotify.max_user_watches
fs.inotify.max_queued_events
вот так
nano /etc/sysctl.d/99-inotify.conf
вставить туда
fs.inotify.max_user_instances = 524288
fs.inotify.max_user_watches = 1048576
fs.inotify.max_queued_events = 163840
сохраняем настройку
sysctl --system
перезагрузка
reboot
проверка
cat /proc/sys/fs/inotify/max_user_instances
cat /proc/sys/fs/inotify/max_user_watches
cat /proc/sys/fs/inotify/max_queued_events
locales:
настройки locales должны соответствовать русской локали ru_RU.UTF-8
nano /etc/default/locale
вставить туда
LANG=ru_RU.UTF-8
LC_ALL=ru_RU.UTF-8
перезагрузить
reboot
Создайте рабочую директорию:
Это может быть как просто /opt так и любая другая специально выделенная директория , в которой скрипт будет создавать все необходимые файлы
Открытие портов (Опционально):
Если используется фаервол (ufw), разрешите порты:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 8080/tcp
Запуск скрипта (пошаговая инструкция)
chmod +x base.sh
./base.sh
Скрипт должен запускаться от пользователя с sudo-доступом, так как он устанавливает пакеты и изменяет системные настройки.
Режимы установки
После запуска скрипт предложит выбрать режим:
Выберите режим:
Режим 1 - использовать существующие volumes (по умолчанию)
Режим 2 - удалить всё и поставить заново
Введите 1 или 2 [1]:
при вводе пустого значения - будет считаться 1 режим
|
Режим 1: Использовать существующие данные (предпочтительно)
Сохраняются:
Базы данных
Конфигурации
Пользовательские файлы
Подходит для обновления или перезапуска
Скрипт прочитает .env, appsettings.json, пароли и т.д.
Режим 2: Полная переустановка
Удаляются:
Все Контейнеры
Все образы
Все волюмы
Папка questionnaire-studio/
Пользователь etl
Создаются:
Новые пароли
Новые SSH-ключи
Новые конфигурационные файлы
Подходит для чистого развертывания или тестирования
В режиме 2 все данные будут утеряны. Рекомендуется делать бэкап (описаны ниже).
|
Этапы работы скрипта
Этап 1: Проверка и установка зависимостей
Устанавливает curl, openssh-client, locales, jq (если отсутствуют)
Устанавливает локаль ru_RU.UTF-8 (важно для корректного отображения русского языка)
Если локаль не применяется, потребуется перезагрузка сервера.
|
Этап 2: Проверка системных требований
Проверяет наличие docker-compose
Проверяет доступ к docker.expasys.ru
Этап 3: Выбор версии QSPRO
Скрипт:
Запрашивает список тегов с https://docker.expasys.ru/v2/questionnaire-studio-pro/tags/list
Фильтрует теги по формату ГГГГ.ММ.ДД.НННН
Выводит список доступных версий
Предлагает выбрать:
Номер версии
L — для latest
Ввести вручную (например, 2024.10.01.1234)
Этап 4: Выбор локали и часового пояса
Язык: фиксированно ru_RU.UTF-8
Часовой пояс: выбор из списка (по умолчанию Europe/Moscow)
Этап 5: Генерация паролей
Автоматически генерируются пароли:
POSTGRES_PASSWORD — для пользователя postgres
QSPRO_PASSWORD — для пользователя qspro (приложение)
DWH_PASSWORD — для пользователя dwh (аналитика)
ETL_PASSWORD — для пользователя etl (JupyterHub)
Пароли генерируются как UUID без дефисов.
|
Этап 6: Генерация SSH-ключей
Ключи создаются в questionnaire-studio/expasys_keys/
Имя: expasys_ssh_rsa (приватный) и expasys_ssh_rsa.pub (публичный)
Используются для SSH-доступа от Cronicle к JupyterHub
Этап 7: Создание конфигурационных файлов
Скрипт генерирует:
.env — переменные окружения
docker-compose.yml — оркестрация сервисов
appsettings.json — настройки .NET-приложения
pgbouncer.ini, userlist.txt, postgresql.conf — настройки БД
Caddyfile — прокси-конфигурация
jupyterhub_config.py — конфигурация JupyterHub
requirements.txt — Python-пакеты для аналитики
Этап 8: Настройка inotify
Скрипт проверяет и устанавливает параметры ядра Linux:
fs.inotify.max_user_instances=524288
fs.inotify.max_user_watches=1048576
fs.inotify.max_queued_events=163840
Этап 9: Запуск контейнеров
Происходит поэтапно:
Скачивание образов (docker-compose pull)
Запуск db, pgbouncer, app-master — для миграций
Создание пользователей и БД
Настройка pg_hba.conf (scram-sha-256)
Запуск остальных сервисов: caddy, jupyterhub, cronicle, nocodb, воркеры
Этап 10: Настройка SSH-интеграции
Устанавливается openssh-server в jupyterhub
Настройка sshd_config
Копирование ключей
Тест SSH-подключения от cronicle к jupyterhub
Создание тестовой задачи в cronicle
Структура проекта после установки:
./questionnaire-studio/
├── .env
├── appsettings.json
├── Caddyfile
├── cronicle_task.json (временный файл)
├── DirectoryPath/ (volume)
├── docker-compose.yml
├── docker.logs
├── Dockerfile.jupyterhub
├── Dockerfile.pgbouncer
├── Dockerfile.postgres
├── expasys_keys/
│ ├── expasys_ssh_rsa
│ └── expasys_ssh_rsa.pub
├── expasysbi_install.log
├── jupyterhub_config.py
├── pgbouncer.ini
├── postgresql.conf
├── requirements.txt
├── test_script.py (временный файл)
├── userlist.txt
├── version.app.txt
├── views/ (volume)
└── wwwroot/ (volume)
Доступ к сервисам
QSPRO (мастер) 8080 http://localhost:8080
Caddy (прокси) 80 http://localhost
* Caddy перенаправляет / → мастер-нода, /bi → мастер и т.д.
|
Логи и диагностика:
Скрипт создает:
docker.logs — логи всех контейнеров
expasysbi_install.log — конфигурационные файлы и настройки
Команды для проверки:
docker-compose ps # статус контейнеров
docker-compose logs app-master # логи мастера
docker-compose logs pgbouncer # логи пула
Секреты и безопасность
Где хранятся пароли:
.env — содержит все пароли
userlist.txt — пароли для pgbouncer
expasysbi_install.log — содержит пароли в открытом виде!
Не передавайте expasysbi_install.log по небезопасным каналам!
|
Рекомендации:
Удалите expasysbi_install.log после установки
Ограничьте доступ к папке questionnaire-studio/
Используйте .env в .gitignore, если в Git
Бэкапы
Создаем бэкапы:
заходим в контейнер:
docker exec -it db bash
создаем бэкап:
pg_dump -U qspro -Fc expasys > expasys_docker_backup.dump
* он создастся в текущей директории докера
|
выходим из контейнера:
exit
копируем файл бэкапа из докера на хост-машину в "укромное место" (в моем случае это выглядит так):
docker cp db:/expasys_docker_backup.dump /opt/questionnaire-studio/expasys_docker_backup.dump
Восстановление базы данных из бэкапов:
копируем из хостовой машины в контейнер db:
docker cp /opt/questionnaire-studio/expasys_docker_backup.dump db:/expasys_docker_backup.dump
заходим в контейнер:
docker exec -it db bash
восстанавливаем бд expasys из бэкап файла
pg_restore -U qspro -d expasys -v /expasys_docker_backup.dump
заходим и проверяем:
psql -U qspro -d expasys
\c expasys
\dt
Вольюмы
Все Волюмы находяться по стандартному пути пути:
/var/lib/docker/volumes/
у меня выглядит так:
brw------- 1 root root 8, 1 авг 21 10:36 backingFsBlockDev
-rw------- 1 root root 65536 авг 21 11:40 metadata.db
drwx-----x 3 root root 4096 авг 21 11:40 questionnaire-studio_caddy_data
drwx-----x 3 root root 4096 авг 21 11:39 questionnaire-studio_data
drwx-----x 3 root root 4096 авг 21 11:39 questionnaire-studio_views
drwx-----x 3 root root 4096 авг 21 11:39 questionnaire-studio_wwwroot
Типичные ошибки и решения:
docker-compose not found Не установлен Установите docker-compose
curl: command not found Не установлен sudo apt install curl
pg_isready timeout Проблемы с PostgreSQL Проверьте docker logs db
appsettings.json not found Файл удален Скопируйте из контейнера или режим 2
user etl not found Пользователь удален Режим 2 или вручную создать
