Payload CMS на Ubuntu 24.04: пошаговая установка
Если вы выбираете headless CMS для проекта на Next.js и хотите, чтобы схема контента жила в коде — с типами, git-диффами и код-ревью, а не собиралась мышкой в чужой админке, — Payload CMS один из немногих вариантов, где это работает по умолчанию, а не через костыли. Ниже — пошаговая установка Payload CMS на чистый Ubuntu 24.04: от подготовки сервера до продакшен-запуска с PostgreSQL, PM2 и Nginx с SSL.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Что такое Payload CMS и когда он подходит
Payload — TypeScript-first headless CMS, начиная с третьей мажорной версии встроенная прямо в Next.js App Router: это не отдельный сервер с REST API где-то сбоку, а пакет, который подключается к вашему Next.js-приложению и добавляет админку по маршруту /admin, REST- и GraphQL-эндпоинты, а также Local API для прямых вызовов из серверных компонентов без похода по сети.
Ключевая идея — схема контента описывается в TypeScript-файлах (коллекции, поля, хуки, права доступа), а не настраивается через UI. Это даёт то, чего не хватает в WordPress или в UI-ориентированных конструкторах: миграции схемы попадают в git, ревьюер видит изменение полей в диффе пул-реквеста, а типы для фронтенда генерируются автоматически из конфига — не нужно вручную синхронизировать интерфейсы.
Payload имеет смысл, если у вас уже есть (или планируется) Next.js-приложение, команда пишет на TypeScript и вам нужна кастомная логика доступа или хуков, которую проще выразить кодом, чем накликать в панели. Если нужен классический отдельный CMS-бэкенд без Next.js на фронте — присмотритесь к Strapi, он ближе к традиционной модели headless CMS с собственным независимым сервером.
Минимальные требования для установки: Node.js 20 или новее, база данных (PostgreSQL, MySQL, SQLite или MongoDB — выбор адаптера) и сервер с 1-2 vCPU и от 2 ГБ RAM для небольшого проекта. Под нагрузкой с активной админкой и генерацией изображений комфортнее с 4 ГБ.
Подготовка сервера
Начинаем с чистого Ubuntu 24.04. Обновляем систему и создаём рабочего пользователя без root-прав:
apt update && apt upgrade -y
adduser deploy
usermod -aG sudo deploy
su - deploy
Настраиваем файрвол — открываем только SSH, HTTP и HTTPS:
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
Если базовая защита сервера ещё не настроена — сделайте это до установки CMS, а не после: см. первичную настройку и безопасность Ubuntu 24.04 и отдельно настройку файрвола ufw, если нужны более тонкие правила.
Если оперативной памяти меньше 2 ГБ, добавьте swap — сборка Next.js (next build) при недостатке RAM может упасть с OOM прямо посреди билда:
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверNode.js, pnpm и системные зависимости
Payload и Next.js под капотом требуют Node.js 20 LTS или новее. Ставим через официальный репозиторий NodeSource, а не через apt — версия в стандартных репозиториях Ubuntu заметно старее:
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
node -v
npm -v
Payload рекомендует pnpm как менеджер пакетов — он быстрее ставит зависимости и экономит место за счёт общего хранилища пакетов между проектами. Включаем через встроенный в Node.js corepack:
sudo corepack enable
corepack prepare pnpm@latest --activate
pnpm -v
Также понадобится git — если ещё не установлен:
sudo apt install -y git
PostgreSQL для хранения данных
Payload поддерживает несколько адаптеров базы данных: PostgreSQL, MySQL, SQLite и MongoDB. Для продакшена на VPS практичнее всего PostgreSQL — зрелая экосистема миграций, предсказуемая производительность и то, что почти наверняка уже стоит на вашем сервере под другие проекты.
| Адаптер | Когда выбирать |
|---|---|
| PostgreSQL | Продакшен по умолчанию: транзакции, зрелые миграции, хорошо масштабируется |
| SQLite | Локальная разработка и совсем небольшие проекты без нагрузки |
| MySQL | Уже есть инфраструктура на MySQL, нет причин заводить второй движок |
| MongoDB | Устаревающий вариант для Payload — команда проекта делает акцент на SQL-адаптерах |
Ставим PostgreSQL и создаём базу с пользователем:
sudo apt install -y postgresql postgresql-contrib
sudo -u postgres psql -c "CREATE USER payload WITH PASSWORD 'СЛОЖНЫЙ_ПАРОЛЬ';"
sudo -u postgres psql -c "CREATE DATABASE payloadcms OWNER payload;"
Если нужны детали по настройке аутентификации, ролей и pg_hba.conf — это подробно разобрано в отдельной статье про установку PostgreSQL на Ubuntu 24.04. Здесь для локального подключения (Payload и Postgres на одном сервере) достаточно строки подключения вида:
postgres://payload:СЛОЖНЫЙ_ПАРОЛЬ@localhost:5432/payloadcms
Создание и настройка проекта Payload CMS
Генерируем проект официальным CLI — он спросит адаптер базы данных, шаблон (blank или с примером блога) и менеджер пакетов:
npx create-payload-app@latest myproject
cd myproject
Выбираем PostgreSQL как адаптер при первом запросе CLI. На выходе получаете обычный Next.js-проект с добавленными файлами:
src/
app/
(payload)/ # маршруты админки и API, сгенерированные Payload
collections/ # ваши коллекции — схема контента как код
payload.config.ts # главный конфиг: коллекции, адаптер БД, плагины
.env
Открываем .env и проверяем/правим переменные окружения:
DATABASE_URI=postgres://payload:СЛОЖНЫЙ_ПАРОЛЬ@localhost:5432/payloadcms
PAYLOAD_SECRET=сгенерированный_секрет
PAYLOAD_SECRET — ключ для подписи сессий и токенов, генерируем случайную строку и никогда не коммитим её в git:
openssl rand -base64 32
Ставим зависимости и прогоняем первую миграцию, которая создаст таблицы под ваши коллекции:
pnpm install
pnpm payload migrate
Запускаем dev-сервер, чтобы создать первого администратора через веб-интерфейс:
pnpm dev
Открываем http://IP_СЕРВЕРА:3000/admin (если порт 3000 временно открыт в ufw для теста или через SSH-туннель — не оставляйте 3000 открытым наружу постоянно), заводите первого пользователя-администратора и на этом dev-этап закрываем Ctrl+C.
Хранилище медиафайлов и продакшен-запуск
По умолчанию загруженные файлы (изображения, документы) складываются на локальный диск сервера. Для одного сервера без реплик это рабочий вариант, но у него два ограничения: диск не резервируется автоматически вместе с базой данных, и если позже вы решите масштабироваться на несколько инстансов, локальные файлы не будут видны второму серверу.
Для продакшена разумно с самого начала подключить S3-совместимое хранилище через официальный плагин:
pnpm add @payloadcms/storage-s3
В payload.config.ts подключаем плагин, указывая endpoint, бакет и коллекцию, для которой он применяется — подойдёт как облачный S3, так и self-hosted MinIO на своём сервере, если хотите держать файлы у себя, а не у стороннего провайдера.
Дальше собираем прод-билд и проверяем, что он стартует:
pnpm build
pnpm start
pnpm start поднимает next start на порту 3000 в форграунде — для постоянной работы нужен менеджер процессов. Ставим PM2 и запускаем через него:
sudo npm install -g pm2
pm2 start pnpm --name payload -- start
pm2 save
pm2 startup
Последняя команда выведет строку с sudo env PATH=... — выполните её, чтобы PM2 поднимал приложение автоматически после перезагрузки сервера.
Ставим Nginx как реверс-прокси перед приложением:
sudo apt install -y nginx
Конфиг /etc/nginx/sites-available/payload:
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
}
}
sudo ln -s /etc/nginx/sites-available/payload /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
Дальше выпускаем SSL-сертификат. Certbot с плагином для Nginx — самый простой путь для одного домена; если сертификатов много и нужна автоматизация через API, сравнение подходов есть в статье Certbot или acme.sh: что выбрать для сервера:
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d example.com
Бэкапы и обслуживание
Payload хранит весь контент в базе данных — значит бэкап базы это бэкап сайта (плюс отдельно файлы медиа, если они на локальном диске, а не в S3/MinIO). Простой cron для ежедневного дампа PostgreSQL:
0 3 * * * pg_dump -U payload payloadcms | gzip > /home/deploy/backups/payload-$(date +\%F).sql.gz
Не забудьте ротацию старых дампов и вынос копий за пределы сервера — локальный бэкап на том же диске не спасает при отказе диска или взломе.
При обновлении версии Payload проверяйте changelog на предмет breaking changes в миграциях — перед pnpm update на проде стоит прогнать обновление и pnpm payload migrate сначала на staging-копии базы. Логи PM2 стоит ротировать через pm2-logrotate, иначе файл логов будет расти без ограничений:
pm2 install pm2-logrotate
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Обязательно ли PostgreSQL, можно поставить SQLite?
Для теста и локальной разработки SQLite подходит и экономит время на установку отдельной СУБД. Для продакшена под реальную нагрузку рекомендуется PostgreSQL — он лучше держит конкурентный доступ и имеет более зрелую систему миграций в экосистеме Payload.
Сколько RAM нужно для Payload CMS?
Для небольшого сайта с несколькими редакторами хватает 2 ГБ, но это ориентир, а не гарантия — конкретная цифра зависит от объёма медиа, числа коллекций и параллельных запросов к API. Если сборка (pnpm build) регулярно падает по памяти, это первый сигнал добавить RAM или swap.
Чем Payload отличается от Strapi?
Strapi — независимый сервер с собственной админкой и REST/GraphQL API, который можно подключить к любому фронтенду. Payload с третьей версии физически встроен в Next.js-приложение: это удобно, если фронт и так на Next.js, но означает более тесную связку с этим фреймворком, чем у Strapi.
Как обновить Payload до новой версии без даунтайма?
Разверните обновлённую версию на отдельном инстансе или staging-окружении с копией продакшен-базы, прогоните миграции там, проверьте админку и API, и только после этого катите обновление на прод — с бэкапом базы перед стартом миграции.
Можно ли использовать Payload без Next.js на фронте?
Да, фронтенд может быть на чём угодно — Payload отдаёт REST и GraphQL API независимо от того, что рендерит витрину. Next.js нужен только для самого приложения Payload (админки и API-слоя), которое разворачивается на сервере.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →