> For the complete documentation index, see [llms.txt](https://docs.iexexchanger.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.iexexchanger.com/knowledge-base/servery-domeny-i-infrastruktura/overview/process-map/pm2.md).

# Что такое PM2

PM2 — менеджер процессов Node.js. В iEXExchanger он запускает серверный рендеринг клиентского сайта: Nginx передаёт запрос внутреннему Node.js-процессу, а PM2 следит за его состоянием и поднимает после сбоя.

## Где находится и кто управляет

У PM2 нет пункта в административной панели iEXExchanger. Все действия выполняются через SSH от системного пользователя — владельца клиентского сайта.

PM2 не управляет Laravel, PHP-FPM, PostgreSQL, Redis, Horizon, Pulse или Reverb. Эти процессы принадлежат системным службам и Supervisor.

```mermaid
flowchart LR
    A["Посетитель"] --> B["Nginx"]
    B --> C["127.0.0.1:4000"]
    D["PM2"] --> E["SSR iexexchanger"]
    E --> C
    E --> F["Серверная часть iEXExchanger"]
```

Подготовка Node.js и клиента описана в [инструкции установки](https://docs.iexexchanger.com/ustanovka-i-obnovlenie/ustanovka), а эта страница фиксирует штатную рабочую конфигурацию без расхождений.

## Штатный ecosystem-файл

В корне клиентского проекта используется `ecosystem.config.cjs`:

```javascript
module.exports = {
    apps: [
        {
            name: 'iexexchanger',
            script: 'dist/exchanger/server/server.mjs',
            cwd: __dirname,
            instances: 1,
            exec_mode: 'fork',
            autorestart: true,
            watch: false,
            max_memory_restart: '1G',
            env: {
                NODE_ENV: 'production',
                PORT: 4000,
                HOST: '127.0.0.1',
                PM2: 'true',
            },
            log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
            error_file: 'logs/err.log',
            out_file: 'logs/out.log',
            merge_logs: true,
            time: true,
            wait_ready: true,
            listen_timeout: 10000,
            kill_timeout: 5000,
            exp_backoff_restart_delay: 100,
        },
    ],
};
```

Ключевые условия:

* имя процесса — `iexexchanger`;
* один экземпляр;
* режим `fork`;
* внутренний адрес — `127.0.0.1:4000`;
* точка входа — `dist/exchanger/server/server.mjs`;
* рабочий каталог — корень клиентского проекта;
* приложение отправляет PM2 сигнал готовности, поэтому `wait_ready` оставляется включённым.

Не создавайте второй ecosystem-файл и не меняйте имя, порт, `instances` или `exec_mode`, пока не проверен существующий процесс и Nginx upstream.

## Почему один fork-процесс

Cluster распределяет Node.js-приложение между несколькими процессами, но требует подтверждённой stateless-архитектуры и отдельной проверки сессий, кеша, WebSocket, памяти и корректного завершения. Штатный SSR iEXExchanger использует один fork-процесс. Не устанавливайте `instances: "max"` только ради предполагаемого ускорения.

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

Войдите от владельца клиентского сайта и перейдите в корень проекта:

```bash
whoami
cd <ПУТЬ_CLIENT>
test -f ecosystem.config.cjs
test -f dist/exchanger/server/server.mjs
mkdir -p logs
pm2 start ecosystem.config.cjs --env production
pm2 describe iexexchanger
pm2 logs iexexchanger --lines 100
```

Если server entrypoint отсутствует, сначала выполните production-сборку по инструкции поставки. Не запускайте PM2 на исходном файле вместо собранного SSR.

Проверка внутреннего ответа:

```bash
curl -I -H 'Host: <КЛИЕНТСКИЙ_ДОМЕН>' http://127.0.0.1:4000/
```

Затем откройте публичный HTTPS-домен. Состояние `online` само по себе не доказывает, что SSR отвечает правильной сборкой и подключается к правильному API.

## Автозапуск после перезагрузки

От владельца клиентского сайта:

```bash
pm2 startup
```

PM2 выведет одну команду с повышенными правами. Проверьте указанного пользователя и путь, выполните именно её, затем снова от владельца сайта сохраните проверенный список:

```bash
pm2 save
```

`pm2 save` сохраняет все процессы текущего пользователя. Сначала удалите только ошибочные дубликаты и убедитесь, что в списке один `iexexchanger`.

## Обновление клиентского сайта

После успешной production-сборки и проверки entrypoint:

```bash
cd <ПУТЬ_CLIENT>
pm2 restart ecosystem.config.cjs --only iexexchanger --update-env
pm2 describe iexexchanger
pm2 logs iexexchanger --lines 100
```

Затем проверьте внутренний и публичный ответ. Только после успешной проверки выполните `pm2 save`.

Не используйте cluster reload для штатного fork-процесса и не удаляйте весь список PM2 при обновлении одного сайта.

## Пользователь и разные списки PM2

У каждого системного пользователя собственный PM2-контекст. Команды от `root` и владельца клиентского сайта показывают разные списки.

Если `pm2 list` пуст:

1. выполните `whoami`;
2. установите владельца файлов клиентского проекта;
3. войдите под этим пользователем;
4. повторите `pm2 list` и `pm2 describe iexexchanger`.

Не запускайте вторую копию от `root`: она создаст другой автозапуск, журналы и права файлов и может занять тот же порт.

## Наблюдение

```bash
pm2 list
pm2 describe iexexchanger
pm2 logs iexexchanger --lines 100
pm2 monit
```

Контролируйте число рестартов, CPU, память, сигнал готовности, порт, ошибки подключения к серверной части и рост `logs/err.log` и `logs/out.log`. Настройте ротацию, но не удаляйте журнал вместо исправления причины.

## Частые проблемы

| Симптом                           | Что проверить                                                                    |
| --------------------------------- | -------------------------------------------------------------------------------- |
| `pm2 list` пуст                   | Системного пользователя и его домашний PM2-контекст                              |
| Процесс `errored`                 | Наличие entrypoint, рабочий каталог, Node.js, порт и последние 100 строк журнала |
| Частые рестарты                   | Исключение, память, занятый порт и внешние зависимости                           |
| После перезагрузки процесса нет   | Команду `pm2 startup`, пользователя службы и последний `pm2 save`                |
| Публичный сайт возвращает 502     | `127.0.0.1:4000`, состояние SSR и Nginx upstream                                 |
| После обновления старый интерфейс | Время сборки, активный каталог, entrypoint, PM2 restart, Nginx и кеш             |
| SSR обращается не к тому API      | Переменные production, `cwd` и restart с `--update-env`                          |

Официальные правила ecosystem-файла и автозапуска приведены в [PM2 Application Declaration](https://pm2.keymetrics.io/docs/usage/application-declaration/) и [Startup Script](https://pm2.keymetrics.io/docs/usage/startup/). Краткая инструкция iEXExchanger также доступна в [разделе управления сервером](https://docs.iexexchanger.com/help-center/upravlenie-serverom/pm2).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.iexexchanger.com/knowledge-base/servery-domeny-i-infrastruktura/overview/process-map/pm2.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
