Skip to content

Docker and external services

devhost can give a Docker container, or any server something else runs, an HTTPS hostname. It routes to a port published on this machine; it cannot reach container names or addresses inside a Docker network.

Publish the container’s port on the host, for example ports: ["4100:4100"] in Compose, then declare the service as external with managed = false:

[services.preview]
managed = false
port = 4100
host = "preview.hello.localhost"

devhost claims the hostname and port, waits until the port accepts connections, and routes to it. It never starts, stops, or restarts the container.

  • An external service cannot have a command, injectPort, or port = "auto"; routing it takes a fixed port.
  • Its health check can be the default TCP check, an explicit tcp port, or an http URL, but not process, since devhost owns no process for it.
  • The Services panel tags it external and offers no restart; recover it outside devhost.
  • A repository that contains an external service cannot switch worktrees.

To start the container from another service of the stack, add that service to dependsOn:

[services.infra]
command = ["bun", "run", "dev:infra"] # starts the containers
health = { process = true }
[services.preview]
managed = false
dependsOn = ["infra"]
port = 4100
host = "preview.hello.localhost"

When devhost should start and stop the container itself, make it an ordinary service whose command runs Compose in the foreground:

[services.api]
command = ["docker", "compose", "up", "--build", "api"]
port = 4000
host = "api.hello.localhost"
health = { http = "http://127.0.0.1:4000/healthz" }

This works because Compose publishes 4000:4000 on the host. Health URLs must use 127.0.0.1, localhost, or ::1; a Docker-internal name such as http://api:4000 is rejected.