[Bug] Compose services cannot join a pre-existing external Docker network (background workers are unreachable from shared services)
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
servicemodel's fields areimage, build, dockerfile, buildArgs, ports, dependsOn, environment, volumes, command, restart, advanced, exposed, exposedPort, domain, …— there is nonetworks. openship.json's published schema does not contain the stringnetworkat any level.openship service createhas 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:
{
"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.
Source: oblien/openship