Repository navigation
feat: Use a free port when 3939 is in use and --port isn't given - #73
Conversation
| # Another process took the default port after we checked it | ||
| create_kwargs["ports"] = {"3939/tcp": None} | ||
| host_port = None | ||
| container = start_container(client, create_kwargs, image_name) |
There was a problem hiding this comment.
This logic feels overly complicated to me. There is a default of 3939, but it will find an available port, unless you specify a port, in which case it will fail if that one is not available. That's already complex. But the way this code resolves that seems convoluted. Can we simplify at all?
There was a problem hiding this comment.
Simplified in ccbd2d4. choose_port, PortInUseError, the retry after a failed start, and the host_port/args.port juggling are gone. What's left: port = args.port, or 3939 if it's free, or None to have Docker assign one, which is read back after the container starts.
I tried dropping the free-port check too and relying on Docker's start error, but Docker Desktop doesn't report a port held by a host process. The container started, and with-connect talked to the other process on 3939. So the check stays. The cost of dropping the retry is that a port taken between the check and the start now fails with Docker's "port is already allocated" error.
57e37f4 to
2f9b025
Compare
a525257 to
ccbd2d4
Compare
|
Looks good to me now. Just needs rebase. |
An explicit --port (or the action's port input) is used as is. Otherwise with-connect uses 3939, or lets Docker assign a free port if 3939 is taken, so several Connect instances can run at once. CONNECT_SERVER has the port. Fixes #30. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Without --port, use 3939 if it's free, and otherwise have Docker assign a free port. This drops choose_port, PortInUseError and the retry after a failed start. Losing the race between the check and the start gives Docker's "port is already allocated" error, which is rare and clear. The check before starting stays: Docker Desktop doesn't report a port held by a host process, so Connect would start and with-connect would talk to the other process. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ccbd2d4 to
7d663ad
Compare
Fixes #30.
Behavior
--port Ngiven: used as is. If N is taken, Docker's error is reported.--port, 3939 free: uses 3939.--port, 3939 in use: Docker assigns a free port. with-connect reads it back from the container and printsPort 3939 is in use. Using port N.on stderr.CONNECT_SERVERalways has the port in use. This lets several Connect instances run at once without picking ports by hand, which is what posit-sdk-py does with a shell one-liner.The check binds
("", 3939), the same as Docker publishing on all interfaces. It's needed because Docker Desktop doesn't report a port held by a host process: without the check, the container starts and with-connect waits on, and talks to, the other process. If something takes 3939 between the check and the container start, Docker's "port is already allocated" error is reported and the failed container is removed. There's no retry for that race.Action
The
portinput has no default, and--portis only passed when the input is set. A workflow that setsport: 3939explicitly gets the strict behavior. The README documents both the CLI option and the action input.Verification
Real runs against
ghcr.io/posit-dev/connect:lateston Docker Desktop, withREADME.mdas a stand-in license, so Connect starts and then fails the license check:Port 3939 is in use. Using port 54060.Port 3939 is in use. Using port 54069.--port 3939while held by another container:Failed to start container ... port is already allocated, with no container left behind.Unit tests cover parsing,
is_port_free, the default port, the Docker-assigned fallback, an explicit port, and a missing port binding.🤖 Generated with Claude Code