Start commands
A proxy site is only half a site. Apache forwards myapp.test to
localhost:3000, but something still has to be listening on that port, and that is usually
a terminal tab you forgot to open.
Give a proxy site a start command and the switch on its row starts it too. Switching
the site on runs npm run dev, php artisan serve or whatever you type. Switching it off
stops it. An active site is then a site that actually answers.
Setting one up
Open the site with Edit, or press New and choose Proxy. Below the port is an optional Start command box with two fields:
- Folder: the project directory the command runs in. Browse opens Finder.
- Command: one line, exactly as you would type it in a terminal.
Press Update and the command starts straight away if the site is switched on. The presets under the field fill in the common ones with one click.
What you can type
The command runs in your login shell, the same zsh your terminal opens, so it sees the
same PATH: nvm, bun, Composer, Herd and everything else your shell profile sets up. That
means a command that works in Terminal works here.
Chain steps with &&. The next step only runs if the one before it succeeded:
npm run dev
bun run start
./run.sh
php artisan serve --port=$PORT
php artisan migrate --force && php artisan serve --port=$PORT
composer install && npm install && npm run dev
$PORT is set to the site's proxy port, so a command can follow the port you chose in
Vhostly instead of repeating it. Many servers read PORT on their own (Next.js, Express,
npm start in most templates). Others need it passed as a flag:
| Server | Command |
|---|---|
| Vite | npm run dev -- --port $PORT --strictPort |
| Laravel | php artisan serve --port=$PORT |
| Rails | bin/rails server -p $PORT |
| Django | python manage.py runserver $PORT |
| Next.js | npm run dev (reads PORT) |
On the row
A site with a start command shows how the process is doing next to the PROXY badge:
| Badge | Meaning |
|---|---|
| STARTING | The command is running, and nothing answers on the port yet. A first compile can take a while. |
| RUNNING | Something answers on the proxy port. The site is up. |
| EXITED | The command finished with code 0. This is normal for pm2 start, which hands the server to its own daemon and returns. |
| FAILED | The command exited with an error before the site came up, or crashed later. |
Proxy rows have no folder to reveal, so the first action button runs or stops the command instead: play starts it again after a crash, stop ends it without switching the site off.
Preview config (the eye) also shows the command's output, live while it runs. Look there first when a site is stuck on STARTING or turned FAILED.
When it runs, and when it stops
- Switching the site on runs the command. Switching it off stops it.
- Opening Vhostly runs the command of every site that is switched on.
- Quitting Vhostly stops every command it started.
- Editing the site restarts the command when the command, the folder, the port or the name changed.
- Deleting the site stops the command and forgets it.
Stopping is thorough. npm run dev starts node, which starts Vite, so Vhostly signals the
whole process group: SIGTERM first, then SIGKILL for anything still alive five seconds
later. No orphaned dev server keeps holding the port.
If Vhostly is force-quit or crashes, the processes it started are found and stopped the next time it opens, then started again for the sites that are still on.
When the port is already taken
If something already answers on the proxy port when the site is switched on, the command
is not started a second time. This usually means you started the server yourself in a
terminal, and a second copy would only fail with EADDRINUSE. The toast says so, and the
site keeps working through the server that is already there.
To hand an existing server over to Vhostly, stop it in its terminal (or from the Ports panel) and press play on the row.
Where it is stored
Start commands are not part of the Apache config. They live in
~/Library/Application Support/Vhostly/runners.json, keyed by the site's name:
{
"video-editor.test": {
"command": "./run.sh",
"cwd": "/Users/you/workspaces/video-editor"
}
}
The process IDs of running commands are kept next to it in runners.pids.json, which is
how a crashed Vhostly finds them again.
A note on trust
A start command is a shell command, and it runs with your user's permissions, the same as anything you type in Terminal. Vhostly only runs what you saved, and its local API refuses requests from web pages, so a site open in your browser cannot set or start a command.