Сколько RAM нужно для Piwigo
Piwigo — классическая веб-галерея на PHP и MySQL: альбомы, права доступа по группам, автоматические превью, плагины. По сравнению с Nextcloud или PhotoPrism она лёгкая и почти не требует ресурсов сама по себе, но проблема в том, что документация Piwigo называет "минимум 128 МБ на PHP" и умалчивает про MySQL, веб-сервер и генерацию превью под нагрузкой. В этой статье — сколько памяти реально нужно для трёх типовых сценариев: домашний архив, галерея студии с правами доступа и публичный сайт с активной загрузкой фото.
Содержание
- Из чего складывается нагрузка Piwigo на память
- Домашняя галерея: минимальная конфигурация
- Галерея студии/малого бизнеса с правами доступа на альбомы
- Публичная галерея с большим трафиком и загрузками
- Настройка PHP-FPM, MySQL/MariaDB и кэша превью под объём RAM
- Где расходуется память впустую и как её сэкономить
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Из чего складывается нагрузка Piwigo на память
Piwigo — это не один процесс, а связка из нескольких сервисов, и память нужно считать по каждому:
- PHP-FPM — сам движок Piwigo. Один worker-процесс в простое ест 20-40 МБ, но при генерации превью (ресайз через GD или Imagick) кратковременно вылетает за 100-150 МБ на процесс — библиотека декодирует полное изображение в память перед сжатием.
- MySQL/MariaDB — хранит метаданные, теги, права доступа. Сама база у Piwigo компактная (десятки-сотни МБ даже на крупных галереях), но
innodb_buffer_pool_sizeи служебные буферы СУБД съедают фиксированный кусок RAM независимо от размера данных. - Веб-сервер (nginx/Apache/Caddy) — раздаёт статику и превью, память минимальна, но растёт с числом одновременных соединений.
- Генерация derivative-изображений — Piwigo на лету создаёт несколько размеров одной фотографии (thumbnail, small, medium, large, xlarge) и кэширует их в
_data/i/upload/. Первая загрузка альбома после очистки кэша — самый прожорливый по CPU и RAM момент. - Плагины — LocalFilesEditor, Community (приём фото от пользователей), BatchDownloader (упаковка альбома в zip на лету) добавляют накладные расходы поверх базового движка.
Ключевой момент: чем больше pm.max_children в PHP-FPM (то есть чем больше одновременных запросов вы хотите обслуживать), тем больше пиковая память нужна — не размер библиотеки фотографий, а параллелизм.
Домашняя галерея: минимальная конфигурация
Личный архив на 1-2 пользователя, до 10-15 тысяч фото, редкие заходы (раз в день-два), доступ через логин/пароль без публичной ссылки.
- RAM: 1 ГБ — работает, но впритык. MySQL держат на минимуме (
innodb_buffer_pool_size = 128M), PHP-FPM — 2-3 воркера. - RAM: 2 ГБ — комфортный минимум. Есть запас на пересборку кэша превью после массовой загрузки и на бэкапы (
mysqldumpдержит соединение и временные буферы).
Пример пула PHP-FPM под 2 ГБ RAM (файл /etc/php/8.3/fpm/pool.d/piwigo.conf):
[piwigo]
user = www-data
group = www-data
listen = /run/php/piwigo.sock
pm = dynamic
pm.max_children = 4
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
pm.max_requests = 500
php_admin_value[memory_limit] = 256M
memory_limit = 256M — не жадность, а страховка: при импорте RAW-файлов с зеркалки (20-40 МБ каждый) декодирование в GD легко упирается в дефолтные 128 МБ и роняет процесс с Allowed memory size exhausted.
Для такого объёма достаточно младшего VPS с SSD — Piwigo не требователен к диску, но кэш превью на 10-15 тысяч фото легко займёт 5-10 ГБ, так что 40-50 ГБ NVMe с запасом хватает с головой.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверГалерея студии/малого бизнеса с правами доступа на альбомы
Фотостудия, свадебный фотограф, небольшой архив компании: 30-80 тысяч фото, разбивка на приватные альбомы по клиентам через группы доступа, 5-20 человек могут одновременно смотреть свои альбомы (клиенты после съёмки), периодическая массовая заливка (100-500 фото за раз).
- RAM: 4 ГБ — рабочая точка для этого сценария. Хватает MySQL под
innodb_buffer_pool_size = 512M-1G(права доступа по группам — это дополнительные JOIN'ы на каждый запрос альбома, база должна держать индексы в памяти), плюс 6-8 воркеров PHP-FPM для параллельных клиентов.
Права доступа в Piwigo реализованы через таблицы group_access и image_category — на каждый рендер альбома идёт проверка прав по группе пользователя. На небольших базах это незаметно, но если у вас сотни приватных альбомов и активные проверки на каждый запрос, query_cache (в MariaDB — через ProxySQL или на уровне приложения, встроенный query cache из MySQL 8 убрали) и прогретый buffer pool ощутимо разгружают диск.
Конфиг MariaDB под 4 ГБ (/etc/mysql/mariadb.conf.d/60-piwigo.cnf):
[mysqld]
innodb_buffer_pool_size = 768M
innodb_buffer_pool_instances = 1
innodb_log_file_size = 128M
max_connections = 50
tmp_table_size = 64M
max_heap_table_size = 64M
max_connections = 50 с запасом — PHP-FPM с 8 воркерами плюс cron-задачи (уведомления, синхронизация) редко упираются в этот лимит, но при заниженном значении массовая заливка от нескольких клиентов сразу даст Too many connections — этот сценарий разобран отдельно в статье про MySQL и ошибку Too many connections.
Публичная галерея с большим трафиком и загрузками
Публичный фотобанк, портфолио с открытой регистрацией, галерея мероприятия с приёмом фото от участников (плагин Community): 100+ тысяч фото, открытый или полуоткрытый доступ, десятки одновременных посетителей, регулярная заливка от многих пользователей одновременно.
- RAM: 8-16 ГБ — здесь параллелизм PHP-FPM растёт до 16-30 воркеров под пиковую нагрузку, MySQL получает
innodb_buffer_pool_size = 2-4G, и появляется смысл вынести кэш превью на отдельный диск или CDN, чтобы не гонять его через основной storage при каждом запросе.
На этом масштабе главный риск — не база, а одновременная генерация derivative-изображений. Если очистить кэш превью (_data/i/upload/) на большой галерее и пустить на неё поисковый бот или толпу посетителей одновременно, PHP-FPM начнёт параллельно ресайзить десятки оригиналов — каждый воркер на пике жрёт 100-150 МБ, и 16 воркеров разом дают 1.5-2.5 ГБ только на этот процесс. Отсюда практическое правило: никогда не чистите весь кэш превью разом на боевой галерее — прогревайте новый кэш постепенно, альбомами, а не полным rm -rf _data/i/upload/*.
Для публичной приёмки фото (плагин Community) добавьте отдельный лимит в PHP-FPM пул именно для upload-запросов — иначе одна массовая заливка съедает все воркеры и блокирует чтение галереи другими посетителями:
php_admin_value[upload_max_filesize] = 32M
php_admin_value[post_max_size] = 64M
php_admin_value[max_execution_time] = 120
Если помимо самой Piwigo вы держите на том же сервере веб-сервер с активной раздачей превью большому числу одновременных клиентов, на публичных галереях с автоматическим SSL и большим числом доменов/поддоменов альбомов разница между Caddy и nginx в удобстве конфигурации заметна — стоит выбирать заранее, а не переезжать на живом трафике.
Настройка PHP-FPM, MySQL/MariaDB и кэша превью под объём RAM
Сводная таблица распределения памяти по трём сценариям (округлённо, оставляет 300-500 МБ на ядро ОС и системные процессы):
| Компонент | 2 ГБ (дом) | 4 ГБ (студия) | 8-16 ГБ (публичная) |
|---|---|---|---|
| PHP-FPM (max_children × memory_limit) | 4×256М | 8×256М | 16-30×256-384М |
| MySQL/MariaDB (buffer pool + overhead) | 256М | 768М-1Г | 2-4Г |
| Веб-сервер + ОС | ~400М | ~500М | ~800М-1Г |
| Запас под пики (превью, бэкапы, cron) | остаток | остаток | остаток |
Общее правило расчёта pm.max_children: (RAM_для_PHP) / memory_limit, а не наугад. Если выставить 30 воркеров на сервере с 4 ГБ и memory_limit = 256M, при одновременном пике вы уйдёте в OOM — ядро начнёт убивать процессы, и первой жертвой обычно оказывается именно MySQL, потому что у него самый большой резидентный объём. Полезно сразу настроить алерты на использование памяти в Telegram, чтобы увидеть момент, когда сервис подошёл к лимиту, а не постфактум по логам.
Отдельно про Imagick vs GD: Piwigo умеет работать с обеими библиотеками. GD экономнее по памяти на большинстве JPEG, но Imagick быстрее и качественнее на RAW/TIFF и при пакетной обработке — если у вас именно фотостудия с RAW-исходниками, Imagick оправдывает лишние 30-50 МБ на пиковый процесс за счёт меньшего числа "зависших" ресайзов.
Где расходуется память впустую и как её сэкономить
Несколько практических моментов, которые реально снижают нагрузку без потери функциональности:
- Не держите на одном сервере тяжёлый бэкап-скрипт и пиковую нагрузку по галерее.
mysqldumpбез--single-transactionна большой базе блокирует таблицы и параллельно ест память на дамп — планируйте бэкапы на ночное время, минимум трафика. Подробности — в статье про бэкап MySQL и частые ошибки. - Отключайте неиспользуемые плагины. Каждый активный плагин Piwigo подключается на каждый запрос через хук-систему — десяток "на всякий случай" установленных плагинов дают заметный оверхед даже если функциональность не используется.
- Ограничьте число derivative-размеров. По умолчанию Piwigo генерирует 5-6 размеров каждой фотографии. Если сайту не нужен
xlarge(для полноэкранного просмотра) — отключите его в настройкахPhoto sizes: меньше размеров — меньше памяти на генерацию и меньше места на диске под кэш. - Вынесите MySQL на отдельный сервер при росте выше 16 ГБ. Когда PHP-FPM и MySQL конкурируют за RAM на одной машине под пиковой нагрузкой, разнесение по двум серверам часто оказывается дешевле, чем гнаться за одним монстром с 32+ ГБ — тем более что сетевая задержка между VPS в одном датацентре обычно 0.1-0.3 мс и не заметна пользователю.
- Следите за swap. Если видите постоянное использование подкачки на боевой галерее — это симптом заниженного RAM, а не повод "просто добавить своп" — своп на SSD спасает от OOM-килла, но каждая генерация превью с подкачкой в 5-10 раз медленнее, и пользователи это почувствуют как зависшую загрузку альбома.
Если сомневаетесь, сколько памяти закладывать с запасом на рост галереи, общий подход к прикидке разобран в статье сколько оперативной памяти закладывать с запасом — логика применима и к Piwigo, и к соседним CMS.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Хватит ли 512 МБ RAM для Piwigo?
Формально Piwigo запустится и на 512 МБ, но любая генерация превью крупных фото или установка через веб-интерфейс с активным PHP-процессом легко упрётся в OOM. Для стабильной работы даже небольшого архива закладывайте минимум 1 ГБ, комфортно — 2 ГБ.
Piwigo или PhotoPrism — что легче по памяти?
Piwigo существенно легче: PhotoPrism использует модели распознавания лиц и объектов, которые постоянно держат в памяти несколько сотен МБ-1 ГБ даже в простое. Piwigo — классическая CRUD-галерея без ML-компонентов, её базовый порог ниже в 2-4 раза. Если распознавание лиц не нужно, а нужны альбомы и права доступа — Piwigo экономнее. Сравнение по установке — в статье про PhotoPrism на VPS.
Нужен ли отдельный Redis для Piwigo?
Не обязательно — Piwigo не использует Redis "из коробки" для основного кэша, он кэширует derivative-изображения на диске, а не сессии в памяти. Redis имеет смысл добавить только при большом числе одновременных сессий и желании вынести хранение сессий PHP из файловой системы в память.
Что случится, если памяти не хватит при массовой загрузке фото?
PHP-FPM воркер, упёршийся в memory_limit, завершится с ошибкой Allowed memory size exhausted, загрузка конкретного файла оборвётся, но остальные воркеры продолжат работать — сервис не падает целиком, если только MySQL не заденет OOM killer. Настройте memory_limit с запасом под самые крупные исходники, которые реально загружают пользователи.
Как понять, что галерее пора расти по RAM?
Смотрите на free -h в момент пиковой нагрузки (массовая заливка или наплыв посетителей после публикации ссылки) и на SHOW ENGINE INNODB STATUS в MySQL — постоянный swap-in/swap-out или ожидания на буфер-пуле сигнализируют, что текущего объёма мало.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →