Skip to content

feat(compose): opt-in skipDefaultNetwork to avoid Traefik multi-network routing issues#4808

Open
myagizmaktav wants to merge 1 commit into
Dokploy:canaryfrom
myagizmaktav:fix/compose-domain-skip-default-network
Open

feat(compose): opt-in skipDefaultNetwork to avoid Traefik multi-network routing issues#4808
myagizmaktav wants to merge 1 commit into
Dokploy:canaryfrom
myagizmaktav:fix/compose-domain-skip-default-network

Conversation

@myagizmaktav

Copy link
Copy Markdown

Fixes #4807

Problem

addDokployNetworkToService unconditionally attaches every domain-linked compose service to both dokploy-network and the project's implicit default network (the fix for #3562). For services that don't need default-network connectivity (single-service compose apps, or apps managing their own explicit network topology), this dual attachment can make Traefik's Docker provider pick the wrong network's IP for routing — producing a persistent 502 that neither a same-container restart nor a Traefik config reload fixes, only a full container recreate does. Full repro/evidence in #4807.

Change

Adds an opt-in, backward-compatible per-domain boolean skipDefaultNetwork (default false) that lets a domain skip the default network attachment while keeping dokploy-network. Mirrors the existing stripPath-style per-domain flag pattern (same schema/validation/pick-list shape).

  • packages/server/src/db/schema/domain.ts — new skipDefaultNetwork column (NOT NULL, default false) + added to apiCreateDomain/apiUpdateDomain pick lists
  • packages/server/src/db/validations/domain.ts — added to the domainCompose zod schema (compose-only, since this only matters for compose deployments)
  • packages/server/src/utils/docker/domain.tsaddDokployNetworkToService takes an optional skipDefaultNetwork param (defaults to false, i.e. unchanged behavior); call site passes domain.skipDefaultNetwork ?? false
  • apps/dokploy/drizzle/0175_skip_default_network.sql + journal entry — migration for the new column
  • New tests in network-service.test.ts covering the opt-in path (5 new cases); all existing cases for the default/unchanged path still pass as-is
  • Updated 4 existing test fixtures (Domain mock objects in host-rule-format.test.ts, labels.test.ts, forward-auth.test.ts, traefik.test.ts) that needed the new required field for typecheck

Testing

pnpm --filter=@dokploy/server run typecheck   # clean
pnpm --filter=dokploy run typecheck           # clean (pre-existing, unrelated handle-tag.tsx Zod-version error only, confirmed present on canary before this change too)
npx vitest run --config __test__/vitest.config.ts __test__/compose/
# Test Files  26 passed (26)
#      Tests  146 passed (146)

Note on the migration snapshot

I don't have a local Postgres/drizzle-kit toolchain to regenerate apps/dokploy/drizzle/meta/*_snapshot.json. The schema.ts change and migration SQL are minimal and correct (single boolean column, matching the style of the existing 0174 migration) — happy to update the snapshot if you can point me at how you'd like it generated, or if this is something CI/your usual flow regenerates.

Open to discussion

This is meant as a starting point, not a final word on the design — happy to adjust naming (skipDefaultNetwork vs something else), whether this belongs on Domain vs Compose, or add a UI toggle if you'd like one wired in as a follow-up. Wanted to keep this PR focused on the minimal backend capability + tests first.

…etwork routing issues

When a domain is attached to a compose service, addDokployNetworkToService
unconditionally attaches that service to both "dokploy-network" and the
project's implicit "default" network (introduced in Dokploy#3562 so sibling
services stay reachable via Compose's own default networking).

For services that don't rely on the default network for inter-service
connectivity (e.g. single-service compose apps, or apps that already
manage their own explicit network topology), being attached to two
networks can make Traefik's Docker provider select the wrong network's
IP for routing. In a live incident this produced a container that Docker
reported "healthy" while Traefik returned a persistent 502 through
Cloudflare — and neither restarting the same container nor reloading
Traefik's config recovered it; only fully removing and recreating the
container (new container ID, new network endpoint) did.

This adds a new per-domain boolean, `skipDefaultNetwork` (default false,
so all existing behavior and tests are unchanged), that lets a domain
opt out of the "default" network attachment while still keeping
dokploy-network. Mirrors the existing `stripPath`-style per-domain flag
pattern.

- packages/server/src/db/schema/domain.ts: new column + pick lists
- packages/server/src/db/validations/domain.ts: zod validation for the compose domain schema
- packages/server/src/utils/docker/domain.ts: addDokployNetworkToService now
  accepts an optional skipDefaultNetwork flag; call site passes
  domain.skipDefaultNetwork
- apps/dokploy/drizzle/: migration for the new column
- New tests in network-service.test.ts covering the opt-in behavior;
  existing tests for the default (unchanged) behavior still pass
- Updated 4 existing test fixtures (Domain mock objects) that needed the
  new required field to keep typecheck green

Note: apps/dokploy/drizzle/meta/*_snapshot.json was not regenerated —
I don't have a local Postgres/drizzle-kit toolchain to run
`drizzle-kit generate` against. The schema.ts change and migration SQL
are correct and minimal (single boolean column, matching the existing
0174 migration's style); happy to update the snapshot if pointed at how
you'd like it generated, or if CI regenerates it automatically.

All 146 existing tests in apps/dokploy/__test__/compose/ pass, plus 5
new ones for this change. `pnpm --filter=@dokploy/server run typecheck`
and `pnpm --filter=dokploy run typecheck` are clean (the one remaining
handle-tag.tsx Zod-version error pre-exists on canary and is unrelated).
@dosubot dosubot Bot added size:S This PR changes 10-29 lines, ignoring generated files. enhancement New feature or request labels Jul 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request size:S This PR changes 10-29 lines, ignoring generated files.

Projects

None yet

1 participant