There is a port conflict with this site’s domain. Sorry, what? No there isn’t [A LocalWP Addon].

Every Local user has seen it. The dreaded banner; “There is a port conflict with this site’s domain”. And every Local user has done the dance;

  • Restart Local
  • Restart Local again…
  • Reboot computer.

Or if you are up for it;

  • Quit Local
  • Check for lingering LocalWP processes
  • Forget nginx, restart Local
  • And problem still there.

The Problem

Local routes all your .local domains through its own bundled nginx on ports 80/443. When that router can’t bind its ports, you get the banner — with a shrug of a message and a “Use localhost” surrender-option. The banner blames a “conflict”, but conveniently never tells you with what. Helpful!

So why does this happen?

Root cause; Local tracks its router nginx through an in-memory process handle. That’s it. That’s the whole bookkeeping. So after a crash, a force-quit, or a plain lost handle, the old nginx master and/or workers survive as orphans, happily squatting on ports 80/443. The next router start fails with Address already in use, and Local’s own stop() can’t fix it — it only knows about the process it spawned this session. The orphans are invisible to it.

Extra spice; nginx rewrites its workers’ process titles to nginx: worker process, so even pgrep -f won’t find them by path. The sneaky little things have to be caught by what they hold (port 80/443) combined with what binary they map to (Local’s bundled nginx, via lsof). Yes, I spent an evening on that. You’re welcome ;)

The Solution

Router Doctor wraps RouterService.restart — the choke point hit at app boot, on site starts, and (this is the good part) by the error banner’s own Retry button — and sweeps the entire router nginx family first;

  • masters, matched by their -p …/run/router/nginx argument;
  • their workers (child processes);
  • orphaned workers — identified via lsof by holding 80/443 with Local’s own nginx binary.

TERM first, KILL for stubborn survivors, then the normal restart proceeds and binds cleanly. And before you ask; sweeping a healthy router here is harmless by construction, since restart stops-and-starts it anyway.

So the new workflow when the banner appears is; click Retry. The end. That’s the whole workflow. No terminal, no killall, no sacrificial offerings.

[Screenshots missing in action – Will make a screenshot when I get the chance]

Because that’s the second half of the cure; when the sweep finds nothing of Local’s, but port 80/443 is genuinely held by a foreign process — Docker, Apple’s own httpd, herd, e.t.c. — Router Doctor puts up a banner that names the actual culprit with its pid. An error message that tells you what’s wrong. Revolutionary concept, I know.

macOS/Linux only (it needs pgrep/lsof); on Windows the addon just does nothing. You can install it, it just won’t help you.

FAIR WARNING

We’re dealing with relatively low level stuff here, if you’re not comfortable with it, by all means, just reboot your computer.

I only have access to MacOS, I could run tests on Linux, but the problem is not that often, so it would be a looooooong test.

If you don’t need it, then don’t install it.

Get it

Source on GitHub: rmpel/Local-Router-Doctor. Be sure to read the notes.

Install from source;
git clone git@github.com:rmpel/Local-Router-Doctor.git
cd Local-Router-Doctor
./scripts/install.sh # symlinks into Local's addons dir + npm install

Restart Local to make it visible in the Installed addons list, toggle on as usual.

Install from a dist file; grab the latest .tgz from the dist folder, or build it with ./scripts/build.sh, and use the “Install from disk” feature in LocalWP.

Author: Remon Pel

WebDeveloper though not WebDesigner

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Confidental Infomation
stop spam mail