Процессы
Как поручить Joppa запуск серверов разработки и контейнеров Compose в правильном порядке, со встроенным терминалом, запуском при открытии и перезапуском после сбоя.
Вкладка Процессы (P) запускает проект из Joppa: его серверы разработки (скрипты dev из package.json, цели Nx, сервер PHP) и его инфраструктуру (сервисы Docker Compose). У каждого процесса есть состояние, порт и логи.

Анализ проекта
В первый раз нажмите Проанализировать проект в верхней части страницы проекта (рядом с Открыть) или во вкладке. Пока анализ не выполнен, Joppa ничего не запускает: домены остаются не в сети, пока вы сами не запустите сервер. Joppa читает package.json, workspaces и файл Docker Compose, затем по шагам показывает, Что Joppa понял о проекте: его joppa.toml, сервисы, которые он использует, затем его процессы и их домены (подробности — в разделе Добавление проекта › Анализ). Ничего не запускается, пока вы не подтвердите. Анализ открывается сам сразу после добавления проекта, если вы не сняли флажок Проанализировать проект после добавления. Пока проект не проанализирован, под заголовком также показывается баннер Чтобы начать, проанализируйте проект с той же кнопкой.
| Столбец | Содержимое |
|---|---|
| В «Запустить всё» | Снимите флажок, чтобы процесс не запускался вместе с остальными; его по-прежнему можно запустить отдельно |
| Процесс | Его имя: web, api, postgres |
| Команда | bun run dev или сервис Compose |
| Порт | Можно изменить |
| Откуда взят порт | скрипт, конфиг, код, .env, compose или по умолчанию |
| Готов, когда | Для сервера разработки с портом: HTTP-путь, который запрашивает Joppa, чтобы узнать, что сервер готов (по умолчанию /), или tcp |
| Домен | Для процесса с портом: если отмечено, процесс получает этот поддомен домена проекта (пусто — базовый домен) |
Строка «ждёт …» показывает зависимости: сервер разработки ждёт, пока будут готовы контейнеры Compose, от которых он зависит.
+ действие под командой сервера разработки добавляет ему действия.
Как определяется порт
В таком порядке:
- переменная со значением по умолчанию в скрипте (
${PORT:-3000}): Joppa задаёт её значение; --port,-pилиPORT=в скрипте;port:в конфигурации фреймворка (vite.config,astro.config), в том числе в одну строку (server: { port: 5400 }), илиoptions.portцели Nx;PORTв.env;- порт фреймворка по умолчанию: Vite и VitePress 5173, Astro 4321, Next.js, Nuxt, Create React App и Docusaurus 3000, Angular 4200, Wrangler 8787, Vue CLI 8080, Gatsby 8000, Storybook 6006, Expo 8081.
Для другого сервера Node Joppa ищет порт в коде (.listen(3000), process.env.PORT ?? 3000).
Менеджер пакетов берётся из lock-файла, иначе из поля packageManager, иначе npm.
Скрипт каждого пакета
Joppa берёт скрипт dev пакета; если его нет — develop, serve или start, который запускает сервер разработки (react-scripts start, ng serve, expo start…). Продакшен-start (node dist/server.js) пропускается.
Сервер PHP
| Проект | Признак | Команда |
|---|---|---|
| Laravel | файл artisan |
php artisan serve --host=127.0.0.1 --port=${SERVER_PORT:-8000} |
| Symfony, другой PHP | public/index.php и composer.json |
php -S 127.0.0.1:${PORT:-8000} -t public |
Порт берётся из SERVER_PORT (Laravel) или PORT в .env, иначе 8000. php — это закреплённая версия.
Воркеры Laravel

Помимо php artisan serve, Joppa предлагает фоновые процессы, которыми пользуется приложение, — по данным composer.json, .env и кода:
| Процесс | Когда | Команда | Отмечен |
|---|---|---|---|
queue |
QUEUE_CONNECTION не равен sync (в Laravel 11 и новее по умолчанию database) |
php artisan queue:work или команда из composer run dev (queue:listen --tries=1 в стартовых наборах, перечитывает код при каждой задаче) |
да; при sync предлагается неотмеченным |
horizon |
установлен laravel/horizon |
php artisan horizon, вместо queue, когда очередь идёт через Redis |
если QUEUE_CONNECTION=redis |
scheduler |
всегда | php artisan schedule:work |
если приложение планирует задачи (Schedule:: в routes/console.php, $schedule-> в Kernel) |
reverb |
установлен laravel/reverb |
php artisan reverb:start --host=127.0.0.1 --port=${REVERB_SERVER_PORT:-8080} |
если BROADCAST_CONNECTION=reverb |
pail |
установлен laravel/pail |
php artisan pail --timeout=0 |
нет: Joppa и так показывает логи |
Это процессы без порта, кроме Reverb: его порт берётся из REVERB_SERVER_PORT в .env, иначе 8080, и Joppa задаёт эту переменную, чтобы worktree мог его сдвинуть. Неотмеченный процесс остаётся в списке и запускается вручную. Проекту, подключённому к сервису Reverb из Joppa, собственный не нужен: снимите с него флажок.
Монорепозитории
Joppa находит пакеты там, где их объявляет репозиторий:
| Файл | Форма |
|---|---|
package.json |
workspaces (npm, yarn, bun), списком или { "packages": [...] } |
pnpm-workspace.yaml |
packages: |
lerna.json |
packages (по умолчанию packages/*) |
nx.json |
каждый project.json в репозитории, его цели serve / dev и цели, которые выводят плагины Nx (@nx/vite/plugin, @nx/next/plugin) |
Шаблоны apps/*, packages/** (на любой глубине) и исключения !packages/legacy поддерживаются; node_modules, dist и скрытые папки пропускаются. Цель Nx запускается через nx run <проект>:<цель>.
Скрипт dev в корне определяет, какую задачу запускать в каждом пакете и в каких именно:
| Скрипт в корне | Задача | Пакеты |
|---|---|---|
turbo dev, turbo run dev, turbo watch dev |
dev |
все, у которых она есть |
turbo run start:dev --filter=web... |
start:dev |
web |
nx run-many -t serve -p shop admin |
serve |
shop, admin |
nx serve shop, nx run shop:serve |
serve |
shop |
pnpm -r --parallel dev, pnpm --filter ./apps/* dev |
dev |
все / те, что в apps/ |
bun run --filter '@acme/*' dev |
dev |
пакеты из scope @acme |
npm run dev -w apps/web -w apps/api |
dev |
web, api |
Фильтр указывает пакет по имени, папке или шаблону (apps/*, @acme/*); ..., ^, {…} и исключения !docs из Turborepo поддерживаются. Пакет, не входящий в корневой dev, остаётся неотмеченным, если только на него не указывает домен.
Если скрипт dev в корне запускает сразу несколько приложений, Joppa предлагает:
- Запускать по отдельности · своё состояние и логи для каждого приложения (рекомендуется);
- Как есть: корневая команда в одном терминале.
Порт уже занят
Анализ следует за портом доменов: если проект был добавлен на 8001, потому что 8000 был занят, php artisan serve настраивается на 8001 (SERVER_PORT=8001, показано под командой).
Если порт процесса уже прослушивается на машине или зарезервирован другим проектом в Joppa, окно сообщает об этом под его строкой. Уже запущенные процессы этого проекта не учитываются.
Проект резервирует свои порты, даже когда он остановлен: порты своих доменов и порты процессов, отмеченных для «Запустить всё» (5173 у Vite, 8080 у Reverb…). Поэтому два приложения Laravel, добавленные одно за другим, не получат незаметно один и тот же порт Vite, даже если первое не запущено: при одновременном запуске второе упало бы. Сообщение называет проект и процесс: «Порт 5173 зарезервирован в Joppa за myproject (vite), даже когда он остановлен». Если этот другой проект сейчас запущен, сообщение говорит и об этом.
В зависимости от случая:
- Использовать порт 5174: первый следующий порт, который не прослушивается и не зарезервирован. Команда или переменная, задающая порт, меняется вслед за ним.
- Оставить 5173: порт зарезервирован другим проектом; сообщение исчезает, порт остаётся. Оба проекта не смогут работать одновременно.
- Остановить его: порт занят программой, запущенной вне Joppa; открывает окно «Освободить порт» с запущенной командой. Сервер разработки другого проекта останавливается со страницы этого проекта.
Сохранение: на этой машине или для команды
- Сохранить хранит конфигурацию в Joppa, на этой машине.
- Отметьте Записать joppa.toml в репозиторий для команды, чтобы поделиться ею: она записывается в файл
joppa.tomlв корне проекта, который нужно закоммитить. Если этот файл существует, главным считается он. См. справочник по joppa.toml. Чтобы поделиться также доменами, сервисами, базой данных и версиями, воспользуйтесь ссылкой Поделиться конфигурацией в joppa.toml под списком процессов.
Сохранить и запустить запускает всё сразу.
Запуск и остановка
- ▶ Запустить всё / ■ Остановить всё в верхней части страницы проекта или из палитры ⌘ K («Запустить всё: monprojet»). Как только работает хотя бы один процесс, кнопка становится ■ Остановить всё.
- Каждый процесс можно запустить, остановить или перезапустить отдельно, во вкладке или из палитры.
Процессы сгруппированы в Приложения (скрипты «dev») и Инфраструктура (Docker Compose, запускается через docker compose up -d --wait: Joppa ждёт healthcheck). В заголовке указан порядок запуска и сколько процессов запущено. У каждой группы своя кнопка ▶ Запустить всё / ■ Остановить всё, которая затрагивает только её процессы: например, чтобы запустить инфраструктуру без приложений. Как и кнопка проекта, она не трогает процессы, исключённые из «Запустить всё».
Сервисы Joppa (базы данных, кеши) здесь не показаны: они общие для всех проектов. Если проект их использует, об этом напоминает строка: они запускаются первыми, вместе с «Запустить всё», а управляются во вкладке Сервисы (Открыть сервисы).
| Состояние | Значение |
|---|---|
| остановлен | — |
| останавливается | Остановка запрошена, процесс ещё не завершился |
| ожидает | Ждёт процесс, от которого зависит |
| запускается | Запущен, но ещё не отвечает (см. Когда процесс готов) |
| работает | Запущен (процесс без порта) |
| доступен | Отвечает на HTTP-запрос на своём порту |
| неисправен | Порт отвечает, но healthcheck не возвращает код 2xx: код показывается («GET /api/health → 503»). См. Healthcheck |
| сбой | Завершился с ошибкой |
| запущен вне Joppa | Порт уже обслуживает процесс, который Joppa не запускал |
| порт занят | Порт занят процессом, который Joppa запустил для другого проекта (два Vite на 5173): в подробностях указано, каким |
| нет Docker | Сервис Compose, но ни одна среда контейнеров не запущена |
| спит | Остановлен Joppa из-за отсутствия запросов: следующий запрос его разбудит (см. Спящий режим) |
Счётчик ▶ 6/7 рядом с проектом, на боковой панели и на его карточке на странице «Проекты», показывает, сколько процессов из «Запустить всё» запущено; строка состояния внизу окна суммирует все проекты (6/7 процессов). Цвет ▶: зелёный, когда работает всё, оранжевый, когда некоторые остановлены, запускаются или запущены вне Joppa, красный — только когда один из них упал или неисправен. Наведите указатель на счётчик, чтобы увидеть подробности. Синяя z заменяет ▶, когда серверы разработки проекта спят.
Если порт занят другой программой, Joppa сообщает об этом и предлагает Освободить порт.
Если его держит другой проект Joppa (его npm run dev запускает Vite на том же порту по умолчанию), состояние становится «порт занят» с пояснением «процессом dev проекта smoovify, запущенным Joppa». Joppa не предлагает его остановить, а предлагает Запустить на :5174: находит первый свободный порт после этого (на нём никто не слушает, его не использует ни один домен или сервис Joppa), переносит туда процесс так же, как при смене порта домена (его переменная, параметр --port или порт, указанный в скрипте), переводит на новый порт домен, который указывал на старый, сохраняет и запускает. После этого оба проекта работают бок о бок.
Остановка отправляет SIGTERM, а через 6 секунд — SIGKILL всему, что запустил скрипт. Сервер разработки, который продолжает работать после завершения запустившего его скрипта, остаётся под наблюдением Joppa: у него сохраняются журнал, состояние и кнопка остановки.
Из терминала: joppa procs, joppa start|stop|restart <проект> [процесс] и joppa logs <проект> [процесс] (см. Команда joppa). Ассистент вроде Claude Code или Cursor делает то же самое с помощью инструментов list_processes, start_process, restart_process, process_logs и run_process_action MCP-сервера.
Конфигурация изменилась после запуска
Сервер разработки читает свой .env при запуске, и большинство серверов потом его не перечитывают, даже под bun --watch: они продолжают работать со старыми значениями (старым портом, старым адресом базы данных) и ничего не сообщают. Joppa сравнивает время запуска каждого процесса с датой изменения файлов .env* в папке проекта и в собственной папке процесса (.env, .env.local, .env.development…, без .env.example и резервной копии .env.joppa-backup). Если один из этих файлов изменился после запуска — неважно, записал его Joppa или вы, — процесс помечается «конфигурация изменилась после запуска», а баннер над таблицами предлагает «Перезапустить затронутые процессы». Пометка исчезает, как только процесс перезапускается.
Сервисов Compose это не касается: Docker Compose читает .env в момент up.
Запуск при открытии Joppa
Переключатель Запускать при открытии Joppa выполняет «Запустить всё» для проекта при каждом запуске Joppa. Это настройка вашей машины: она никогда не записывается в joppa.toml.
Если joppa.toml приходит через git pull с изменёнными командами, Joppa не запускает их сам: уведомление сообщает, что проект не был запущен. Проверьте команды, затем нажмите Запустить всё: после этого запуск при открытии снова работает как обычно.
Перезапуск после сбоя
Настройка Перезапускать после сбоя определяет, сколько раз Joppa перезапускает упавший сервер разработки: никогда, 1, 2, 3 (по умолчанию), 5 или 10 раз.
- Пауза между перезапусками удваивается: 1 с, 2 с, 4 с, 8 с… до 30 с.
- Счётчик обнуляется после 60 секунд стабильной работы.
- Когда попытки исчерпаны, Joppa сдаётся и сообщает об этом: «снова завершился с ошибкой после 3 перезапусков: Joppa больше не перезапускает его.»
- Остановка, запрошенная вами, отменяет ожидающий перезапуск.
Эта настройка касается только серверов разработки (не контейнеров Compose) и относится только к вашей машине.
Исправление упавшего процесса
Когда процесс останавливается окончательно (Joppa сдался после перезапусков или перезапуск выключен), в верхней части страницы проекта появляется красный баннер, какая бы вкладка ни была открыта: процесс, причина остановки и последние строки, которые он вывел.

- Исправить перезапускает его вместе с теми, от которых он зависит, не трогая остальные процессы.
- Открыть терминал показывает весь его журнал.
- Спросить ассистента открывает ассистента в папке проекта, с уже введёнными ошибками, командой и кодом выхода.
- Скрыть прячет баннер до следующего сбоя.
Когда процесс готов
Сервер разработки с портом доступен, когда отвечает на HTTP-запрос, а не просто когда его порт принимает подключения: Joppa запрашивает GET / на его порту, и засчитывается любой ответ, даже 404 или 500. Терминал отмечает этот момент: «готов за 1.2 с (GET / → 200)». Процессы, которые его ждут («ждёт …», dependsOn), запускаются только после этого.
Столбец Готов, когда в анализе (поле probe в joppa.toml) меняет то, что запрашивает Joppa:
| Значение | Готов, когда |
|---|---|
| (пусто) | GET / получает ответ |
/health, /up… |
Этот путь получает ответ |
tcp |
Порт принимает подключения |
Если порт принимает подключения, но в течение 30 секунд не приходит ни одного HTTP-ответа, или если он отвечает по другому протоколу, Joppa всё равно считает его готовым. После этого Joppa больше ничего у него не запрашивает: он только проверяет, что порт по-прежнему отвечает. Сервисы Docker Compose готовы, когда проходит их healthcheck, а если его нет — когда отвечает их порт.
Healthcheck
Готовность ещё не значит, что сервер в порядке: API, запущенный без своей базы данных, часто отвечает 503 на своём порту. С полем healthcheck в joppa.toml (healthcheck = "/api/health") Joppa запрашивает этот путь каждые 2 секунды, пока процесс работает:
- ответ 2xx: процесс доступен, зелёный;
- другой ответ или его отсутствие: процесс неисправен, красный, с тем, что получил Joppa («GET /api/health → 503» или «нет ответа на /api/health»). Об этом сообщает и его домен на странице проекта, а счётчик проекта становится красным.
Он снова становится зелёным, как только путь возвращает 2xx. Без healthcheck Joppa, как и раньше, смотрит только на порт.
Спящий режим
Когда открыто много worktree и у каждого свои серверы разработки, память быстро заканчивается. Joppa усыпляет серверы разработки проекта, которым никто не пользуется: после 15 минут без запросов к его доменам он останавливает их и помечает как спит.

Следующий запрос к одному из его доменов будит их:
- прокси удерживает запрос;
- Joppa перезапускает усыплённые серверы разработки вместе с теми, от которых они зависят;
- как только сервер домена готов, запрос передаётся ему.
Страница, которой пришлось бы ждать дольше 3 секунд, показывает «Пробуждение web…» и сама обновляется каждую секунду, пока сервер не ответит. Остальные запросы (fetch, файлы, WebSocket HMR) ждут до 90 секунд. HMR Vite сам переподключается после пробуждения.
Переключатель Усыплять через … без запросов во вкладке Процессы задаёт задержку (от 5 мин до 2 ч) или выключает спящий режим, для каждого проекта отдельно. По умолчанию он включён для окружений worktree и выключен для остальных проектов. Это настройка вашей машины, она никогда не записывается в joppa.toml.
- Усыпляются только серверы разработки: контейнеры Docker Compose и сервисы Joppa продолжают работать.
- Joppa не усыпляет проект, процесс которого запускается, перезапускается или выполняет действие, проект, ни один домен которого не ведёт к серверу разработки (ни один запрос не смог бы его разбудить), а также ничего не усыпляет, когда прокси остановлен.
- Вкладка браузера, оставленная открытой без активности, не мешает усыплению: когда вы к ней вернётесь, клиент HMR переподключится и разбудит сервер.
- ▶ тоже будит спящий процесс; ■ Остановить всё выводит его из спящего режима: запрос его больше не перезапустит.
Состояние спит показывается во вкладке, в столбце состояния доменов, в терминале и на счётчике проекта (синяя z и «4 спят» в строке состояния). Инструмент MCP list_processes возвращает его как asleep.
Действия
Действие — это разовая команда, привязанная к процессу: migrate → php artisan migrate, seed → php artisan db:seed, test → bun test. Оно запускается одним щелчком рядом с именем процесса во вкладке Процессы или на панели терминала, открытого на этом процессе. Его вывод пишется в терминал процесса, между «▶ migrate $ php artisan migrate» и «migrate: готово» (или «migrate: ошибка (код 1)»).
- Оно выполняется в папке процесса, с его переменными окружения, независимо от того, запущен процесс или нет.
- Повторный щелчок во время выполнения останавливает его.
- Одно и то же действие одновременно выполняется только один раз.
Действия объявляются в анализе (Пересмотреть анализ): + действие под командой сервера разработки, затем имя и команда. Joppa предлагает migrate, seed и test для Laravel, test и lint для проекта на JavaScript. Если у проекта есть joppa.toml, действия записываются в него. Ассистент запускает их инструментом run_process_action MCP-сервера.
Laravel Boost
Когда laravel/boost есть в composer.json проекта, на вкладке Процессы появляется карточка Laravel Boost. Отдавать Boost ассистентам — и Joppa запускает php artisan boost:mcp, а MCP-сервер Joppa передаёт его инструменты (схема базы, последняя ошибка, журнал, документация…) вашим ассистентам для этого проекта. Подключите их к Joppa один раз (Настройки › Командная строка › Подключить ассистентов): они достают до Boost во всех ваших проектах Laravel из любой папки, без .mcp.json в каждом. Claude Desktop, у которого нет папки, тоже.
- Boost работает с PHP от Joppa: закреплённой версией проекта и его
.php.ini, а не системнымphp. - Он запускается, когда вы его включаете; после перезапуска Joppa — при первом вызове ассистента.
- Laravel читает конфигурацию один раз при запуске: когда меняется
.env, файл вconfig/илиroutes/,composer.lock,.php-versionили.php.ini, Joppa перезапускает Boost перед следующим вызовом. - Карточка показывает состояние (работает · 10 инструментов, готов, запустится при первом вызове, не запустился с тем, что вывел PHP), инструменты, pid и число вызовов. Перезапустить запускает его заново.
- Выключенный, он останавливается; останавливается он и при выходе из Joppa.
Выбор хранится в config.json (поле boost проекта), только на этом компьютере. Если пакет есть в composer.json, но ещё не в vendor/, сначала выполните composer install.
Встроенный терминал
⌘ J открывает терминал внизу окна с любого экрана. В свёрнутом виде он показывает по квадратику состояния на процесс; в развёрнутом — вкладку Все, а затем по вкладке на каждый процесс.

- ⌕ фильтр: показывает только строки, содержащие заданный текст.
- ● следить: держит прокрутку на последних строках.
- Очистить, Развернуть / Свернуть.
- Изменение размера: потяните верхний край (или ↑ / ↓ с клавиатуры); двойной щелчок возвращает высоту по умолчанию. Joppa запоминает последнюю высоту.
Joppa хранит последние 5 000 строк каждого процесса. При сбое терминал предлагает полезное действие: Освободить порт или Перезапустить.
Выделите строки, чтобы отправить их своему агенту кода (Спросить Claude Code) или скопировать с контекстом (Копировать с контекстом): проект, полный путь к его папке, процесс и его команда. См. Ассистент.
Оболочка в проекте
Кнопка + на панели терминала (Новая оболочка) открывает ваш shell (тот, что в вашей сессии macOS, обычно zsh) в папке проекта, в новой вкладке Оболочка 1, Оболочка 2… Это настоящий терминал: вы вводите в нём свои команды (git, php artisan, bun…) с тем же PATH, что и у процессов проекта (закреплённая версия Node, PHP из Joppa).
Каждая оболочка принадлежит своему проекту: при переходе к другому проекту его оболочки пропадают с панели, но продолжают работать, и, вернувшись, вы найдёте их в том же виде. × на вкладке закрывает оболочку; если убрать проект, закрываются и его оболочки. Когда оболочка завершается (exit), Перезапустить открывает новую в том же месте.