Документация

Установка MeenuCMS

Четыре шага от покупки до работающего сайта.

  1. Купите лицензию

    Оставьте заявку — пришлём счёт с договором. После оплаты код активации придёт на email и появится в кабинете.

  2. Скачайте архив

    В личном кабинете — последняя версия MeenuCMS одним zip-архивом.

  3. Установите на сервер

    Скриптом на Timeweb Cloud — около 20 минут, или вручную на любой сервер по инструкции ниже.

  4. Пройдите мастер

    Откройте /install на своём сайте, введите секрет установки, код активации, данные бизнеса и владельца — готово.

Способ 1 · Timeweb Cloud

Автоматическая установка на Timeweb Cloud

Скрипт сам создаст сервер в вашем аккаунте Timeweb Cloud, настроит его и установит MeenuCMS: Node.js 24, MongoDB с паролем, nginx, бесплатный сертификат HTTPS с автопродлением, автозапуск, файрвол и ночные резервные копии. Занимает 15–25 минут; всё, что нужно, скрипт спрашивает по шагам.

Что понадобится

Что Где взять
Аккаунт Timeweb Cloud с пополненным балансом timeweb.cloud — регистрация и раздел «Финансы»
API-токен Timeweb Cloud панель Timeweb → «API и Terraform» → «Создать токен»
Домен сайта у любого регистратора; проще всего — купить там же, в Timeweb
Архив meenu-cms-X.Y.Z.zip личный кабинет → «Скачать»
Код активации MEENU-XXXX-XXXX-XXXX-XXXX письмо после оплаты или личный кабинет
Компьютер с Windows 10/11, macOS или Linux в Windows всё нужное уже есть; на macOS и Linux — утилита jq

Сервер скрипт создаёт сам — заказывать его в панели заранее не нужно.

Регистрация в Timeweb Cloud

  1. Откройте timeweb.cloud, нажмите «Регистрация», подтвердите почту и телефон.
  2. Выберите тип аккаунта: физическое лицо или организация (для закрывающих документов — организация или ИП).
  3. В разделе «Финансы» пополните баланс. Сервер для MeenuCMS стоит около 1 000–1 500 ₽ в месяц, списание посуточное. Timeweb не создаёт сервер, если на балансе меньше его месячной стоимости.

Скрипт предложит тарифы не слабее 2 vCPU, 4 ГБ памяти и 40 ГБ диска — этого хватает с запасом — и покажет цену до создания сервера.

API-токен

Токен нужен, чтобы скрипт создал сервер и DNS-запись от вашего имени.

  1. Панель Timeweb Cloud → в меню слева «API и Terraform».
  2. «Создать токен»: имя любое (например, meenu-install), срок — 1 день.
  3. Скопируйте токен — он показывается один раз.

Токен даёт полный доступ к аккаунту, поэтому скрипт его нигде не сохраняет. После установки удалите токен в том же разделе.

Домен

Сайт будет открываться по вашему домену: sushi-example.ru, shop.example.ru или кириллическому суши-пример.рф. Направить его на сервер скрипт предложит двумя способами:

  • домен в Timeweb (куплен там или его NS-серверы — ns1.timeweb.ru…ns4.timeweb.ru) — A-запись скрипт создаст сам, а старые A-записи этого имени предложит удалить;
  • домен у другого регистратора (REG.RU, RU-CENTER, Beget и т. д.) — скрипт покажет, какую A-запись добавить в панели регистратора, и подождёт, пока она заработает.

Домен должен указывать только на новый сервер: лишняя A-запись (заглушка регистратора, старый сайт) помешает выпуску сертификата HTTPS.

Запуск скрипта

Скрипт запускается на вашем компьютере, а не на сервере.

Windows 10 и 11

  1. Нажмите «Пуск», наберите PowerShell и откройте его (права администратора не нужны).
  2. Скопируйте команду, вставьте в окно PowerShell правой кнопкой мыши и нажмите Enter:
[Net.ServicePointManager]::SecurityProtocol = 'Tls12'; irm https://meenu.ru/install/timeweb.ps1 | iex

Больше ничего ставить не нужно: PowerShell и SSH уже есть в Windows. Если скрипт напишет, что не найден «клиент OpenSSH», включите его: «Параметры» → «Приложения» → «Дополнительные компоненты» → «Добавить компонент» → «Клиент OpenSSH».

macOS и Linux

Откройте «Терминал». На macOS сначала поставьте утилиту jq (нужен Homebrew), на Linux — curl и jq:

brew install jq                                   # macOS
sudo apt install -y curl jq openssh-client        # Linux

Запустите установку:

bash <(curl -fsSL https://meenu.ru/install/timeweb.sh)

Что спросит скрипт

  1. Домен — кириллический домен скрипт сам переведёт в punycode. Для домена второго уровня спросит, открывать ли сайт и по www. (с переадресацией на основной адрес). Затем — email для Let’s Encrypt: туда придёт письмо, если продление сертификата сломается.
  2. API-токен Timeweb — вставьте его (в Windows — правой кнопкой мыши) и нажмите Enter. Символы при вставке не отображаются — так и задумано. Скрипт проверит токен и покажет баланс.
  3. SSH-ключ — скрипт создаст ключ .ssh\meenu_timeweb_ed25519 в папке пользователя. Это ваш ключ от сервера — не удаляйте его.
  4. Сервер — «создать новый»: выбор локации (по умолчанию Санкт-Петербург) и тарифа с ценой, подтверждение перед созданием. Или «уже есть»: IP пустого сервера Ubuntu 22.04/24.04 — скрипт один раз спросит пароль root и добавит на сервер ключ.
  5. DNS — автоматически или вручную у регистратора (см. «Домен»). Скрипт ждёт, пока домен начнёт указывать на сервер, — обычно 2–15 минут.
  6. Архив MeenuCMS — перетащите скачанный meenu-cms-X.Y.Z.zip мышкой в окно и нажмите Enter. В Windows можно просто нажать Enter — скрипт сам найдёт архив в папке «Загрузки».

Дальше 10–15 минут скрипт работает сам, ход виден на экране: обновление системы, Node.js 24, MongoDB, файрвол, MeenuCMS и её автозапуск, nginx, сертификат HTTPS и проверка его автопродления, резервные копии, проверка сайта.

Прервать можно в любой момент (Ctrl+C). Запустите ту же команду снова и укажите тот же домен — скрипт продолжит с сохранённого места, уже сделанное на сервере не сломается. Журнал настройки хранится на сервере — /root/meenu-install.log.

В конце Windows-версия сама скопирует секрет установки в буфер обмена и откроет мастер установки в браузере.

Мастер установки

В конце скрипт покажет адрес и секрет установки:

  1. Откройте https://<ваш домен>/install.
  2. Введите секрет установки из итога скрипта.
  3. Введите код активации MEENU-XXXX-XXXX-XXXX-XXXX — лицензия привяжется к этому серверу.
  4. Укажите название бизнеса, данные владельца и первую точку.

Готово — дальше всё настраивается в админке https://<ваш домен>/admin: оплата, зоны доставки, меню, команда. Не забудьте удалить API-токен в панели Timeweb.

Обслуживание сервера

Задача Как
Обновить MeenuCMS в админке — «Применить обновление» в баннере новой версии
Войти на сервер ssh -i ~/.ssh/meenu_timeweb_ed25519 root@<IP>
Журнал CMS journalctl -u meenu-cms -f
Перезапустить CMS systemctl restart meenu-cms
Резервная копия сейчас meenu-backup
Настройки /var/www/meenu-cms/.env
Забыли секрет установки grep INSTALL_SECRET /var/www/meenu-cms/.env

Резервные копии базы, загруженных фото и настроек делаются каждую ночь в 04:30 в /var/backups/meenu-cms и хранятся 14 дней. Они лежат на том же сервере, поэтому дополнительно включите в панели Timeweb автоматические бэкапы сервера (страница сервера → «Бэкапы»).

Сертификат HTTPS продлевается сам: дважды в сутки certbot проверяет срок и обновляет сертификат примерно за месяц до окончания.

Если что-то не так

Что видно Что сделать
«Токен не принят» скопирован не целиком или истёк — создайте новый токен
Сервер не создаётся на балансе меньше месячной стоимости тарифа — пополните баланс
Скрипт долго ждёт DNS проверьте A-запись у регистратора и уберите старые; у некоторых регистраторов изменения доходят до 1–2 часов. Можно выйти и запустить скрипт позже
Ошибка certbot домен указывает не только на новый сервер — исправьте DNS и запустите скрипт снова
«CMS не ответила» войдите на сервер и посмотрите journalctl -u meenu-cms -n 100
Код активации «привязан к другой установке» отвяжите прежний сервер в личном кабинете
Нет доступа по SSH панель Timeweb → сервер → «Консоль», вход по паролю root со страницы сервера

Если не получается — напишите в поддержку из личного кабинета и приложите снимок экрана с ошибкой.

Способ 2 · Любой сервер

Ручная установка на свой сервер

Архив содержит готовую сборку: исходников и node_modules в нём нет, ставить зависимости не нужно.

Требования

  • Linux x86_64 или ARM64 с glibc: Ubuntu 22.04+, Debian 12+. Для Alpine (musl) нужна отдельная сборка под linuxmusl-x64 — запросите её в поддержке; ей нужен Alpine 3.20+ (musl 1.2.5+) и пакет libstdc++ (в образе node:24-alpine он уже есть).
  • Node.js 24.15 или новее: node -v. Установка — https://nodejs.org (LTS) или NodeSource.
  • MongoDB 6.0 или новее (на этом же сервере или внешняя, например Atlas).
  • unzip: sudo apt install unzip.
  • Домен и обратный прокси с HTTPS (ниже — пример для nginx).

Установка

sudo useradd --system --create-home --home-dir /opt/meenu-cms meenu
sudo -u meenu unzip meenu-cms-X.Y.Z.zip -d /opt/meenu-cms
cd /opt/meenu-cms
sudo -u meenu cp .env.example .env
sudo -u meenu nano .env

В .env обязательно укажите:

  • PUBLIC_URL — адрес сайта, как его видят гости: https://shop.example.ru;
  • MONGO_URL — строка подключения к MongoDB;
  • PORT — порт приложения (по умолчанию 4321);
  • за nginx на этой же машине: HOST=127.0.0.1 и TRUST_PROXY=127.0.0.1.

Необязательно: INSTALL_SECRET — свой секрет мастера установки. Сгенерируйте его: openssl rand -base64 24 (короткий или явно слабый секрет сервер не примет и не стартует). Не задан — сервер выпустит его сам при первом запуске (см. ниже).

NODE_ENV=production launcher выставляет сам. Остальные настройки (бренд, оплата, интеграции) задаются в админке.

Первый запуск

cd /opt/meenu-cms && sudo -u meenu node launcher.mjs

В выводе появятся строки Система не установлена. Откройте …/install и Секрет установки: …. Откройте адрес и пройдите мастер:

  1. Секрет установки — из строки Секрет установки: … (или ваш INSTALL_SECRET из .env; при LOG_LEVEL=error или silent строки в журнале не будет — выпустите секрет командой ниже). Он доказывает, что установку проводит тот, у кого есть доступ к серверу: посторонний, открывший адрес раньше вас, мастер не пройдёт. Секрет печатается один раз; потеряли — выпустите новый (прежний сразу перестаёт действовать, CMS перезапускать не нужно):

    cd /opt/meenu-cms && sudo -u meenu node launcher.mjs install:secret
  2. Код активации MEENU-XXXX-XXXX-XXXX-XXXX из письма после оплаты или из личного кабинета (серверу нужен доступ в интернет к сайту Meenu). Код привязывается к этому серверу; при переезде отвяжите прежнюю установку в личном кабинете.

  3. Название бизнеса, владелец и первая точка.

Остановить — Ctrl+C; дальше запускайте через systemd.

Если на шаге 2 активирован не тот код, сбросьте незавершённую установку — активация стирается, выпускается новый секрет, мастер начинается заново:

cd /opt/meenu-cms && sudo -u meenu node launcher.mjs install:reset

Если секрет задан в INSTALL_SECRET, сброс его не меняет: смените значение в .env и перезапустите сервис — иначе прежний секрет продолжает действовать. После завершения установки команда отказывает: лицензию тогда меняют в админке, раздел «Лицензия».

Автозапуск (systemd)

/etc/systemd/system/meenu-cms.service:

[Unit]
Description=Meenu CMS
After=network-online.target mongod.service
Wants=network-online.target

[Service]
Type=simple
User=meenu
WorkingDirectory=/opt/meenu-cms
ExecStart=/usr/bin/node /opt/meenu-cms/launcher.mjs
Restart=always
RestartSec=5
KillMode=control-group
TimeoutStopSec=30

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now meenu-cms
journalctl -u meenu-cms -f                          # журнал
journalctl -u meenu-cms | grep 'Секрет установки'   # секрет мастера (до установки)

Путь к node проверьте командой which node (при установке через nvm он другой).

nginx

# Connection: upgrade для WebSocket, close — для обычных запросов (блок http, один на сервер)
map $http_upgrade $connection_upgrade {
	default upgrade;
	''      close;
}

# Адрес по координатам: широта и долгота идут в строке запроса и не должны копиться в журнале (блок http)
map $uri $log_request {
	~^/api/public/(address/reverse|delivery/resolve) 0;
	default 1;
}

server {
	listen 443 ssl;
	server_name shop.example.ru;
	access_log /var/log/nginx/access.log combined if=$log_request;
	# сертификат — certbot --nginx -d shop.example.ru

	client_max_body_size 200m;  # фото блюд до 10 МБ, видео сторис до 200 МБ
	proxy_read_timeout 300s;    # видео сторис сервер перекодирует прямо в запросе загрузки

	location / {
		proxy_pass http://127.0.0.1:4321;
		proxy_http_version 1.1;
		proxy_set_header Host $host;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header X-Forwarded-Proto $scheme;
		# WebSocket: лента заказов, экран кухни, табло выдачи, чат
		proxy_set_header Upgrade $http_upgrade;
		proxy_set_header Connection $connection_upgrade;
	}
}

Без заголовков Upgrade/Connection сокеты не открываются: лента заказов обновляется только опросом раз в 30 секунд, экран кухни и табло отстают.

С nginx обязательно TRUST_PROXY=127.0.0.1 в .env: иначе все гости видны с адреса прокси и ограничения запросов становятся общими на весь сайт.

Что лежит в каталоге

Путь Что это
launcher.mjs супервизор: запускает CMS, перезапускает при сбое, применяет обновления
launcher.prev.mjs предыдущий launcher (появляется после его самообновления)
launcher.pending.json, launcher.rejected.json служебные файлы самообновления launcher
current.json какая версия из releases/ работает
releases/<версия>/ версии приложения (хранятся 3 последние)
.env ваши настройки (в архивах обновлений его нет — не перезаписывается)
uploads/ загруженные фото и логотипы
chat-files/ вложения чата по заказам (фото и документы гостей); закрытый каталог, по прямой ссылке не раздаётся
secrets.key ключ шифрования секретов (ключи iiko, мини-приложение VK, push курьера); храните отдельно от дампа
update-log.json история обновлений
bad-releases.json версии, откаченные после падений (автоматически не ставятся)
update-progress.json стадия идущего обновления (экран «Обновляем…» после перезапуска CMS)

Обновление

Когда выходит новая версия, в админке появляется баннер «Доступна версия X · Подробнее»: заметки всех новых версий и кнопка «Применить обновление» (только владелец, при действующей лицензии или в льготный период). Launcher скачивает архив с сервера Meenu, проверяет подпись, запускает новую версию на временном порту и переключается на неё, только если она ответила. При любой ошибке продолжает работать прежняя версия, причина видна в разделе «Обновления» и в update-log.json.

Если в новой версии изменился сам launcher, он обновляется следом: новый файл сначала проверяется самотестом, затем заменяет launcher.mjs (прежний рабочий сохраняется в launcher.prev.mjs), и launcher перезапускается. CMS при этом перезапускается дважды: при переключении на новую версию и при перезапуске launcher (каждый раз — как обычный рестарт). Не прошёл самотест — остаётся прежний launcher, обновление CMS всё равно применено, в разделе «Обновления» — предупреждение.

  • systemd, запуск вручную — launcher заменяет себя в том же процессе (тот же PID), юнит менять не нужно.
  • pm2 (и любой запуск с IPC-каналом) — launcher останавливает CMS и завершается с кодом 75, pm2 поднимает его заново уже с новым launcher.mjs (нужен включённый по умолчанию autorestart).
  • Docker — launcher.mjs вместе с current.json и releases/ должен лежать на томе (volume): иначе пересоздание контейнера вернёт launcher и версию из образа.

Если новый launcher трижды подряд стартует, но CMS под ним не проработала минуту, на четвёртом старте он сам возвращает launcher.prev.mjs и больше не ставится (launcher.rejected.json); в разделе «Обновления» — предупреждение. Если launcher не запускается вовсе, верните прежний вручную:

cd /opt/meenu-cms && sudo -u meenu cp launcher.prev.mjs launcher.mjs && sudo systemctl restart meenu-cms

Если новая версия переключилась, но потом падает раз за разом (5 падений за 10 минут в первые 30 минут после обновления), launcher сам возвращает предыдущую версию. В разделе «Обновления» — «Обновление откатилось: версия X падала после запуска», версия X записывается в bad-releases.json и автоматически больше не ставится (кнопка обновления до неё вернёт ошибку). Более новые версии ставятся как обычно. Повторить установку X после исправления причины: кнопка «Снять пометку и повторить» в разделе «Обновления» (видна владельцу, пока версия есть в списке доступных и обновление можно применить; подтверждение запускает установку заново) — либо удалите её запись из bad-releases.json (или весь файл, если записей больше нет). Изменения данных при откате не отменяются. Если релиз объявил их необратимыми (в его launcher.json стоит "rollback": false), launcher не откатывает сам, а пишет причину в раздел «Обновления» — обратитесь в поддержку. При первой установке (предыдущей версии нет) падающая версия просто перезапускается. Падения из-за недоступной MongoDB (например, после перезагрузки сервера база поднялась позже CMS) откатом не считаются: launcher просто перезапускает CMS, пока база не станет доступна.

Лицензия проверяется раз в сутки. За 30 дней до окончания в админке появится предупреждение; после окончания 14 дней админка работает как обычно, затем закрывается до продления (раздел «Лицензия» остаётся доступным). Витрина и приём заказов работают всегда.

Вручную:

sudo systemctl stop meenu-cms
cd /opt/meenu-cms && sudo -u meenu unzip -o meenu-cms-X.Y.Z.zip
sudo systemctl start meenu-cms

unzip -o добавит releases/X.Y.Z/, обновит launcher.mjs, current.json и эту инструкцию; .env и uploads/ не затрагиваются.

Откат вручную: остановите сервис, впишите в current.json версию из releases/ ({ "version": "1.4.0" }) и запустите. Изменения данных при откате не отменяются, и старая версия не всегда корректно работает с уже изменёнными данными. Откат с версии, где появились необратимые изменения данных (1.0.8: индекс платежей; 1.0.10: долги бонусов и промо заказа), — только через поддержку. Признак — "rollback": false в launcher.json релиза; у уже выпущенного 1.0.8 такого признака может не быть, поэтому откат с 1.0.8 тоже делайте через поддержку.

Резервные копии

Регулярно сохраняйте базу (mongodump --uri "$MONGO_URL" --out /backup/meenu-$(date +%F)), каталог uploads/ и каталог chat-files/ (фото и документы чатов по заказам).

Файл secrets.key в корне установки сохраняйте отдельно от дампа базы: он расшифровывает ключи интеграций. Вместе с дампом он раскрывает их.

Ключом из этого файла шифруются: ключи iiko, защищённый ключ мини-приложения VK и закрытый ключ VAPID для push курьера. Без файла ключи iiko и VK придётся ввести заново, а push курьерам перестанет уходить (ошибка видна в журнале). Ключи банков, FrontPad, Firebase, токены Telegram и бота VK этим ключом не шифруются.

Установка под ключКонсультацияПокупка

Заявка на установкуОбсудим за 15 минутЗаявка на покупку

Перезвоним или напишем, уточним детали сервера и согласуем время.Покажем админку, ответим на вопросы и посчитаем, во что обойдётся запуск: лицензия, сервер, установка.Пришлём на email счёт с договором и доступ в личный кабинет. Код активации и архив — после оплаты.

Как с вами связаться