#846·openship

[Bug] Compose services cannot join a pre-existing external Docker network (background workers are unreachable from shared services)

Author: greersoCreated Sep 6, 2026Updated Sep 12, 2026

What I'm trying to do

Run a background worker as a second service in a compose project, where the worker needs to reach shared singletons (a crawler, a search engine, an LLM host, a DAM) that live on a pre-existing external Docker network the app container is already attached to.

What happens

The worker builds and runs correctly — same commit as the app, right database, healthy:

openship-<project>-worker   openship/<project>-worker:bld_…   Up (healthy)
Datasource "db": PostgreSQL … at "db:5432"
129 migrations found. No pending migrations to apply.

But it is attached to the project network and nothing else:

$ docker inspect … -f '{{range $k,$v := .NetworkSettings.Networks}}{{$k}} {{end}}'
openship-<project>-prod

$ docker exec … getent hosts crawl4ai
(no output)

So every shared service is unresolvable. In our case the worker then claimed jobs off a queue it shared with a correctly-networked worker and failed each one with fetch failed — silently, because the failures land in a job table.

Why it can't be configured around (self-hosted, CLI 0.6.6)

  • The service model's fields are image, build, dockerfile, buildArgs, ports, dependsOn, environment, volumes, command, restart, advanced, exposed, exposedPort, domain, … — there is no networks.
  • openship.json's published schema does not contain the string network at any level.
  • openship service create has no network flag.

The app container reaches the external network because of project-level routing (routeStrategy: container-ip + internalAlias), and a project has exactly one of those. A non-exposed second service gets the private project network only. The one lever that would attach it is making the worker exposed with a domain — publishing a background worker on the internet, which is not acceptable.

docker network connect <external> <worker> after each deploy works, but is undone by the next deploy, so the worker goes silently deaf on a schedule.

What would fix it

A per-service external-network attachment on the service model — the compose networks: + top-level external: true shape:

jsonc
{
  "name": "worker",
  "dockerfile": "Dockerfile.worker",
  "networks": ["magnolia"]     // pre-existing, external; join, don't create
}

Semantics that would be enough for this case: named networks must already exist (error rather than create), the service joins them in addition to its project network, and re-joining is re-applied on every deploy. Aliases on those networks would be a bonus but aren't needed — plain DNS by container name would do.

Workaround in use

Hand-run docker compose stacks outside Openship for the workers, so they can declare the external network themselves. That costs a manual rebuild on every deploy and lets the worker drift behind the app's schema, which is exactly what we adopted Openship to stop doing.