Как установить и настроить Strapi на VPS
Если фронтенд у вас уже отдельно — на Next.js, Nuxt, React Native или в нескольких каналах сразу — а контент нужно хранить и отдавать через API, WordPress и его шаблонизатор становятся лишним звеном. Strapi решает именно эту задачу: это самый популярный open-source headless CMS на Node.js, который отдаёт контент по REST или GraphQL и оставляет вопрос вёрстки фронтенду. Ниже — пошаговая установка Strapi на чистый VPS: от подготовки сервера до рабочего сайта под доменом с SSL.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Что понадобится и какой VPS выбрать
Strapi — это Node.js-приложение с собственным процессом, административной панелью и обычно отдельной базой данных, поэтому к ресурсам сервера он требовательнее, чем статический сайт. Для старта и админ-панели хватает 1 ГБ RAM, но под сборку продакшен-версии (npm run build) на слабой машине легко упереться в OOM — сама сборка на пике может съедать 1-1.5 ГБ памяти. Практический ориентир: от 2 ГБ RAM для комфортной работы, 1-2 vCPU, 20+ ГБ SSD с запасом под медиафайлы и бэкапы базы.
Что понадобится по софту:
- Ubuntu 24.04 LTS (подойдёт и 22.04) на чистом VPS с root- или sudo-доступом;
- Node.js — Strapi 5 официально поддерживает Node.js 18.x, 20.x и 22.x (LTS-ветки), нечётные версии не поддерживаются;
- PostgreSQL как база данных — Strapi умеет работать и с SQLite, и с MySQL, но для продакшена рекомендуют именно PostgreSQL;
- Nginx как reverse proxy перед приложением и Certbot для SSL;
- PM2 для запуска Node.js-процесса как сервиса с автозапуском.
Если у вас уже есть привычка разворачивать сервисы в контейнерах, тот же стек можно поднять через Docker Compose — но в этом гайде разберём классическую установку без Docker, она нагляднее показывает, из чего состоит Strapi изнутри.
Подготовка сервера, Node.js и PostgreSQL
Обновите систему и поставьте базовые пакеты:
apt update && apt -y upgrade
apt install -y curl git build-essential
Node.js ставим из репозитория NodeSource — версию из штатных репозиториев Ubuntu использовать не стоит, она почти всегда устаревшая:
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
apt install -y nodejs
node -v
npm -v
Дальше — PostgreSQL. Подробный разбор установки и первичной настройки есть в отдельной статье про PostgreSQL на Ubuntu 24.04, здесь — минимум, нужный для Strapi:
apt install -y postgresql postgresql-contrib
systemctl enable --now postgresql
Создайте отдельную базу и пользователя под Strapi — не используйте для приложения суперпользователя postgres:
sudo -u postgres psql -c "CREATE DATABASE strapi_db;"
sudo -u postgres psql -c "CREATE USER strapi_user WITH ENCRYPTED PASSWORD 'сложный_пароль';"
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE strapi_db TO strapi_user;"
sudo -u postgres psql -c "ALTER DATABASE strapi_db OWNER TO strapi_user;"
Пароль сохраните — он понадобится в .env приложения. Отдельного системного пользователя под Strapi лучше тоже завести сразу, чтобы процесс не работал от root:
adduser strapi
usermod -aG sudo strapi
su - strapi
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверСоздание проекта и первый запуск
Дальнейшие команды выполняются под пользователем strapi. Создать новый проект проще всего официальным CLI, указав сразу PostgreSQL как базу — тогда мастер сам подготовит нужные конфиги:
npx create-strapi-app@latest my-project --dbclient=postgres --dbhost=127.0.0.1 --dbport=5432 --dbname=strapi_db --dbusername=strapi_user --dbpassword=сложный_пароль
Мастер предложит выбрать шаблон (пустой или с примером контента) и спросит про TypeScript — для боевого проекта разумно сразу соглашаться на TypeScript, переписывать потом дороже. Установка займёт несколько минут — CLI подтянет зависимости и создаст структуру проекта.
Перейдите в каталог и запустите dev-режим, чтобы проверить, что всё поднялось:
cd my-project
npm run develop
По умолчанию Strapi слушает 0.0.0.0:1337. Откройте http://IP_сервера:1337/admin в браузере (если порт закрыт файрволом — временно откройте его или используйте SSH-туннель) и создайте первого администратора — эта форма показывается один раз при первом заходе. После этого дев-сервер можно остановить (Ctrl+C) — дальше настраиваем продакшен-запуск.
Переменные окружения и продакшен-конфигурация
В корне проекта лежит файл .env — именно туда CLI уже вписал параметры подключения к базе. Откройте и проверьте его:
nano .env
Ключевое, на что стоит обратить внимание:
HOST=0.0.0.0
PORT=1337
APP_KEYS=ключ1,ключ2,ключ3,ключ4
API_TOKEN_SALT=случайная_строка
ADMIN_JWT_SECRET=случайная_строка
TRANSFER_TOKEN_SALT=случайная_строка
JWT_SECRET=случайная_строка
DATABASE_CLIENT=postgres
DATABASE_HOST=127.0.0.1
DATABASE_PORT=5432
DATABASE_NAME=strapi_db
DATABASE_USERNAME=strapi_user
DATABASE_PASSWORD=сложный_пароль
DATABASE_SSL=false
APP_KEYS, ADMIN_JWT_SECRET, API_TOKEN_SALT, JWT_SECRET и TRANSFER_TOKEN_SALT CLI обычно генерирует автоматически при создании проекта — но если вы клонируете проект на новый сервер или собирали .env вручную, сгенерируйте их сами и никогда не используйте значения из документации или чужих примеров:
node -e "console.log(require('crypto').randomBytes(16).toString('base64'))"
Выполните команду четыре раза для APP_KEYS (через запятую) и по разу для каждого секрета. Файл .env не должен попадать в git — убедитесь, что он в .gitignore (в шаблоне Strapi это уже так по умолчанию).
В файле config/server.js можно явно задать url — публичный адрес админки и API, это важно, если Strapi стоит за reverse proxy:
module.exports = ({ env }) => ({
host: env('HOST', '0.0.0.0'),
port: env.int('PORT', 1337),
app: {
keys: env.array('APP_KEYS'),
},
url: env('PUBLIC_URL', 'https://cms.vashdomen.ru'),
});
Сборка админ-панели и запуск через PM2
Административная панель Strapi — это отдельное React-приложение, которое нужно собрать перед продакшен-запуском:
npm run build
Если сборка падает по памяти на VPS с 1 ГБ RAM — временно добавьте swap-раздел или соберите проект на машине помощнее и перенесите каталог build, дальше объяснимо проще держать под сборку минимум 2 ГБ.
Для управления процессом в продакшене используйте PM2 — он перезапускает приложение при падении и после перезагрузки сервера:
sudo npm install -g pm2
pm2 start npm --name "strapi" -- run start
pm2 save
pm2 startup
Последняя команда выведет строку с sudo env PATH=... — выполните её от имени пользователя strapi, чтобы PM2 поднимался автоматически при старте системы. Проверить, что процесс жив:
pm2 status
pm2 logs strapi
Как альтернатива PM2 подойдёт systemd-юнит, если вы предпочитаете штатные средства Linux вместо отдельного менеджера процессов — логика та же: описать ExecStart с npm run start в каталоге проекта и включить Restart=always.
Nginx как reverse proxy, домен, SSL и бэкапы
Strapi слушает порт 1337 только на loopback или внутреннем интерфейсе — наружу его отдаёт Nginx. Общий принцип настройки reverse proxy подробно разобран в статье про Nginx как reverse proxy на Ubuntu 24.04, для Strapi конфиг выглядит так:
server {
listen 80;
server_name cms.vashdomen.ru;
client_max_body_size 50M;
location / {
proxy_pass http://127.0.0.1:1337;
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;
}
}
client_max_body_size увеличен намеренно — по умолчанию Nginx режет загрузку файлов на 1 МБ, а в медиатеке Strapi легко встретить картинки крупнее. Активируйте конфиг и перезапустите Nginx:
ln -s /etc/nginx/sites-available/strapi /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx
Домен должен A-записью указывать на IP сервера ещё до выпуска сертификата. Дальше — Certbot, о выборе между ним и alternative-клиентами есть отдельный разбор в статье Certbot или acme.sh:
apt install -y certbot python3-certbot-nginx
certbot --nginx -d cms.vashdomen.ru
Не забудьте про файрвол — если ставили UFW, порт 1337 наружу открывать не нужно, он должен быть доступен только локально; разрешите только 22, 80 и 443.
Отдельно позаботьтесь о бэкапах. У Strapi есть встроенная команда экспорта данных вместе со схемой и медиафайлами:
npx strapi export --file backup_$(date +%F) --no-encrypt
Плюс регулярный дамп самой базы PostgreSQL (pg_dump) — так вы страхуетесь и на уровне приложения, и на уровне СУБД. Оба файла имеет смысл выгружать за пределы сервера — на S3-совместимое хранилище или хотя бы на другую машину.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Strapi упал после npm run build с ошибкой памяти — что делать?
Добавьте временный swap (2-4 ГБ достаточно) на время сборки или соберите проект локально/на более мощной машине и скопируйте готовый каталог build на сервер — саму сборку заново запускать на проде не нужно.
Можно ли использовать SQLite вместо PostgreSQL?
Технически да, Strapi это поддерживает, но для продакшена с реальной нагрузкой и конкурентными запросами SQLite не рассчитан на такой сценарий — переход на PostgreSQL стоит закладывать сразу, миграция данных между базами не тривиальна.
Как обновить Strapi до новой версии?
Через официальный upgrade-инструмент — npx @strapi/upgrade major (или minor/patch) с последующей проверкой changelog на breaking changes и обязательным бэкапом базы перед обновлением.
Порт 1337 нужно держать открытым наружу?
Нет, если перед Strapi стоит Nginx — приложение должно слушать только 127.0.0.1 или внутренний интерфейс, а наружу торчит только 80/443 через reverse proxy.
Чем Strapi отличается от связки WordPress + REST API?
WordPress тоже отдаёт REST API из коробки, но его модель данных заточена под посты и страницы; Strapi изначально спроектирован content-first — типы контента, поля и связи описываются гибко под задачу, без надстроек над блоговым движком.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →