LimeSurvey в Docker Compose: готовый файл
Когда нужна не форма из трёх полей, а полноценная анкета с ветвлением вопросов, квотами и экспортом в SPSS — Google Forms и Typeform быстро упираются в потолок. LimeSurvey закрывает этот класс задач: условная логика, рандомизация ответов, многоязычные опросы, встроенная статистика. Ниже — рабочий docker-compose.yml, с которым инструмент поднимается за 10 минут и не падает под нагрузкой в день сбора данных.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Зачем LimeSurvey, а не облачный сервис
LimeSurvey — open-source платформа для опросов с 20-летней историей (изначально PHPSurveyor). Отличие от SaaS-конструкторов не в красоте интерфейса, а в глубине логики:
- Ветвящаяся логика (relevance equations) — вопрос показывается или скрывается в зависимости от ответов на предыдущие, вплоть до сложных выражений с переменными.
- Квоты — можно остановить опрос по конкретному сегменту ответов, когда набрано нужное количество респондентов.
- Группы вопросов с рандомизацией — снижает эффект порядка при социологических исследованиях.
- Экспорт в SPSS, R, CSV — важно для академических и маркетинговых исследований, где данные потом обрабатываются отдельно.
- Токены и приглашения — можно рассылать персональные ссылки-приглашения и отслеживать, кто ответил, а кто нет, без раскрытия личности в самих ответах.
Минус самостоятельного хостинга — вы отвечаете за бэкапы, обновления и производительность сами. Но это же и плюс: данные респондентов (иногда персональные, иногда медицинские) не уходят в чужое SaaS-хранилище, а остаются на вашем сервере — это часто требование этического комитета или юридического отдела.
Для российской аудитории есть отдельный практический момент: у большинства облачных опросников (SurveyMonkey, Typeform) сложности с оплатой и доступом из РФ. Самостоятельный сервер снимает эту зависимость полностью.
Требования к серверу
LimeSurvey сама по себе не прожорлива — это PHP-приложение с базой данных. Но опрос с сотнями одновременных респондентов и сложной логикой генерирует много PHP-процессов и запросов к БД.
| Сценарий | CPU | RAM | Диск |
|---|---|---|---|
| Личный/малый опрос (до 50 респондентов одновременно) | 1 vCPU | 2 ГБ | 20 ГБ SSD |
| Исследование среднего масштаба (до 300 одновременно) | 2 vCPU | 4 ГБ | 40 ГБ SSD |
| Массовый сбор данных, загрузка файлов в ответах | 4 vCPU | 8 ГБ | 80+ ГБ SSD (файлы ответов растут быстро) |
Если в опросе есть вопросы с загрузкой файлов (сканы документов, фото) — диск стоит закладывать с запасом, это самая частая причина, почему место кончается неожиданно. Для большинства проектов достаточно VPS на 2 vCPU / 4 ГБ.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверDocker Compose файл
Официальный образ martialblog/limesurvey — наиболее поддерживаемый community-образ, синхронизированный со стабильными релизами LimeSurvey. Разворачиваем связку с MariaDB.
Структура каталога:
mkdir -p ~/limesurvey/{db-data,limesurvey-data,upload-data}
cd ~/limesurvey
nano .env
nano docker-compose.yml
Файл .env:
MYSQL_ROOT_PASSWORD=замените_на_сложный_пароль
MYSQL_DATABASE=limesurvey
MYSQL_USER=limesurvey
MYSQL_PASSWORD=замените_на_сложный_пароль_2
LIMESURVEY_ADMIN_USER=admin
LIMESURVEY_ADMIN_PASSWORD=замените_на_сложный_пароль_3
LIMESURVEY_ADMIN_NAME=Admin
LIMESURVEY_ADMIN_EMAIL=admin@ваш-домен.ru
PUBLIC_URL=https://opros.ваш-домен.ru
Файл docker-compose.yml:
services:
db:
image: mariadb:10.11
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
volumes:
- ./db-data:/var/lib/mysql
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 10s
timeout: 5s
retries: 5
limesurvey:
image: martialblog/limesurvey:6-apache
restart: unless-stopped
depends_on:
db:
condition: service_healthy
environment:
DB_TYPE: mysql
DB_HOST: db
DB_PORT: 3306
DB_NAME: ${MYSQL_DATABASE}
DB_USER_NAME: ${MYSQL_USER}
DB_PASSWORD: ${MYSQL_PASSWORD}
DB_TABLE_PREFIX: lime_
ADMIN_USER: ${LIMESURVEY_ADMIN_USER}
ADMIN_PASSWORD: ${LIMESURVEY_ADMIN_PASSWORD}
ADMIN_NAME: ${LIMESURVEY_ADMIN_NAME}
ADMIN_EMAIL: ${LIMESURVEY_ADMIN_EMAIL}
PUBLIC_URL: ${PUBLIC_URL}
volumes:
- ./limesurvey-data:/var/www/html/application/config
- ./upload-data:/var/www/html/upload
ports:
- "127.0.0.1:8080:8080"
networks:
default:
name: limesurvey-net
Порт LimeSurvey нарочно привязан к 127.0.0.1 — снаружи он не должен быть доступен напрямую, впереди должен стоять reverse-прокси с HTTPS (об этом ниже).
Запуск:
docker compose up -d
docker compose logs -f limesurvey
Первый старт занимает 1-2 минуты — образ инициализирует БД и накатывает миграции схемы. В логе должна появиться строка о готовности Apache. После этого админка доступна по http://127.0.0.1:8080/admin (пока только с самого сервера — доступ извне настроим через прокси).
PHP-лимиты, которые ломают сложные опросы
Дефолтные лимиты PHP в образе рассчитаны на средний случай и часто оказываются тесными для реальных исследований — особенно если в опросе много вопросов с загрузкой файлов или экспортируется большой датасет ответов.
Создайте php-limesurvey.ini и подключите его через volume:
; ~/limesurvey/php-limesurvey.ini
upload_max_filesize = 20M
post_max_size = 25M
memory_limit = 512M
max_execution_time = 300
max_input_vars = 5000
max_input_vars — самая коварная настройка: опрос с 60+ вопросами, часть из которых — матрицы с множественным выбором, легко превышает дефолтные 1000 переменных формы, и тогда часть ответов при сохранении просто не долетает до сервера без видимой ошибки.
Добавьте volume в сервис limesurvey:
volumes:
- ./limesurvey-data:/var/www/html/application/config
- ./upload-data:/var/www/html/upload
- ./php-limesurvey.ini:/usr/local/etc/php/conf.d/zz-limesurvey.ini:ro
Пересоздайте контейнер: docker compose up -d --force-recreate limesurvey.
Cron-задачи: приглашения и напоминания
LimeSurvey умеет автоматически рассылать приглашения и напоминания респондентам, но это требует внешнего планировщика — сама она по расписанию ничего не делает. Скрипт application/commands/console внутри контейнера умеет запускать эти задачи из командной строки.
Добавьте на хост-сервер (не внутрь контейнера) задание в crontab:
crontab -e
# Рассылка приглашений и напоминаний по всем активным опросам, каждый час
0 * * * * docker compose -f /home/user/limesurvey/docker-compose.yml exec -T limesurvey php application/commands/console.php plugin execute --target=all --method=sendReminder >> /var/log/limesurvey-cron.log 2>&1
Для конкретного опроса ID можно вызывать sendinvitations и sendreminders через console.php с параметром --surveyid. Если рассылок много, обязательно настройте SMTP в админке (Настройки → Глобальные настройки → Электронная почта) — без внешнего SMTP-релея почта уходящая с сервера, скорее всего, будет попадать в спам или блокироваться провайдером.
HTTPS через Caddy
Простейший вариант reverse-прокси — Caddy, который сам получает и обновляет сертификат Let's Encrypt. Поставьте его на хосте (не обязательно в том же docker-compose) или добавьте отдельным сервисом:
Caddyfile:
opros.ваш-домен.ru {
reverse_proxy 127.0.0.1:8080
}
sudo apt install -y caddy
sudo systemctl restart caddy
Через 10-20 секунд Caddy сам выпустит сертификат и опрос станет доступен по https://opros.ваш-домен.ru. Подробный разбор автоматизации SSL через Caddy — в статье Caddy с авто-SSL: частые ошибки и решения, если сертификат не выпускается с первого раза.
После включения HTTPS обновите PUBLIC_URL в .env на https:// и пересоздайте контейнер — иначе ссылки в письмах-приглашениях будут указывать на http://.
Бэкап опросов и ответов
Данные респондентов — то, что нельзя терять. Бэкапить нужно два места: базу MariaDB (структура опросов, ответы) и каталог upload-data (загруженные респондентами файлы).
Простой скрипт для ежедневного бэкапа:
#!/bin/bash
# ~/limesurvey/backup.sh
set -e
DATE=$(date +%Y-%m-%d)
BACKUP_DIR=~/backups/limesurvey
mkdir -p "$BACKUP_DIR"
docker compose -f ~/limesurvey/docker-compose.yml exec -T db \
mysqldump -u root -p"${MYSQL_ROOT_PASSWORD}" limesurvey | gzip > "$BACKUP_DIR/db-$DATE.sql.gz"
tar czf "$BACKUP_DIR/uploads-$DATE.tar.gz" -C ~/limesurvey upload-data
find "$BACKUP_DIR" -type f -mtime +14 -delete
chmod +x ~/limesurvey/backup.sh
crontab -e
# 30 3 * * * /home/user/limesurvey/backup.sh
Для более надёжной схемы с версионированием и внешним хранилищем подойдёт связка через BorgBackup — она подробно разобрана в статье BorgBackup на Ubuntu 24.04: пошаговая установка. Отдельные подводные камни именно при бэкапе баз MySQL/MariaDB (блокировки таблиц, размер дампа) описаны в статье Бэкап MySQL на сервере: частые ошибки и решения.
Оптимизация под нагрузку в день сбора данных
Если опрос рассылается сразу большой аудитории (например, всем сотрудникам компании или базе клиентов), нагрузка приходит не равномерно, а всплеском в первые часы после рассылки. Несколько практических моментов:
- Увеличьте лимит подключений MariaDB — по умолчанию
max_connectionsв образе часто стоит на 151, при всплеске PHP-воркеров этого может не хватить. Добавьте в команду сервисаdb:--max-connections=300. - Отключите ExpressionManager-логи в проде — в Настройках опроса включённое логирование выражений условной логики заметно замедляет каждый переход между вопросами при сложной relevance-логике.
- LimeSurvey кэширует шаблоны на диске — если сервер на медленном сетевом диске (некоторые бюджетные VPS так делают), первая загрузка страницы опроса после деплоя ощутимо тормозит; на SSD-инстансе это не проблема.
- Если опрос действительно массовый (тысячи одновременных ответов), стоит закладывать сервер с запасом по CPU заранее, а не масштабировать по факту падения — миграция базы LimeSurvey на лету не тривиальна.
Общие практики продакшен-конфигурации Docker Compose (лимиты ресурсов, healthcheck, логирование) разобраны в статье Docker Compose для продакшена: частые ошибки и решения — пригодится, если сервер обслуживает не только LimeSurvey.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Можно ли перенести существующий опрос из другой инсталляции LimeSurvey?
Да, через экспорт .lss-файла структуры опроса и отдельно .csv/.lsr для ответов — в новой инсталляции импортируется через админку (Опросы → Импорт опроса).
Обновляется ли LimeSurvey сама при перезапуске контейнера?
Нет, версия фиксируется тегом образа (6-apache). Для обновления до новой минорной версии меняйте тег и делайте docker compose pull && docker compose up -d — но сначала обязательно сделайте бэкап базы, миграции схемы необратимы без него.
Что делать, если после сохранения сложного опроса часть вопросов пропадает?
Почти всегда это упирается в max_input_vars или post_max_size в PHP — смотрите раздел про PHP-лимиты выше.
Нужен ли отдельный SMTP-сервер для рассылки приглашений?
Крайне рекомендуется. Отправка почты напрямую с IP VPS без настроенных SPF/DKIM записей часто улетает в спам или блокируется получающим сервером; используйте внешний SMTP-релей (Postmark, SendGrid, Yandex почта для домена и т.п.).
Выдерживает ли эта конфигурация одновременное заполнение 500+ респондентами?
На 4 vCPU / 8 ГБ с правильно выставленным max_connections в MariaDB — как правило, да, но это стоит проверить нагрузочным тестом на копии опроса перед реальной рассылкой, а не полагаться на ориентировочные цифры.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →