Dokploy / Dokploy/dokploy

Docker-image apps: any deploy (webhook or API) rewrites the Swarm service spec and drops the app's traefik.* labels → all domains 404

Open
#5,453 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
37.4k
Forks
3k
Avg merge
1d 3h
Merged PRs (30d)
73

Description

Environment
  • Dokploy v0.29.12 (original) and v0.30.6 (after upgrading — still reproduces)
  • Self-hosted on a single-node Docker Swarm (Ubuntu arm64 VM), Traefik as shipped by Dokploy (docker provider, @docker routers)
  • Affected applications are sourceType=docker with a pinned dockerImage (ghcr.io/<org>/<app>:vX.Y.Z), domains added through the Domains tab (one app has 4 hostnames, another has 1), https: true, certificateType: letsencrypt
Summary

Any deploy rewrites the application's Swarm service spec without its traefik.* labels. After the deploy the containers are healthy ("✓ Ready") but Traefik has no router for the app's domains, so every hostname returns Traefik's plain-text 404 page not found.

Reproduced on both deploy entry points:

Deploy path Labels before Labels after
POST /api/deploy/<refreshToken> (webhook, called by CI) 9 0
POST /api/application.deploy + x-api-key 9 0

Both apps (4 domains and 1 domain) are affected; measured 3 times in total, on v0.29.12 and again on v0.30.6.

Evidence

Before a deploy:

$ docker service inspect omt-frontend-31cc8b --format '{{json .Spec.Labels}}'
{"traefik.enable":"true",
 "traefik.http.routers.<app>-web.entrypoints":"web",
 "traefik.http.routers.<app>-web.rule":"Host(\"app.example.com\") || Host(\"accounts.example.com\") || …",
 "traefik.http.routers.<app>-web.service":"omt-frontend",
 "traefik.http.routers.<app>-websecure.entrypoints":"websecure",
 "traefik.http.routers.<app>-websecure.rule":"Host(…)",
 "traefik.http.routers.<app>-websecure.service":"omt-frontend",
 "traefik.http.routers.<app>-websecure.tls":"true",
 "traefik.http.services.omt-frontend.loadbalancer.server.port":"3000"}

After the deploy (service UpdatedAt matches the deployment time, new task Running, same image digest):

$ docker service inspect omt-frontend-31cc8b --format '{{json .Spec.Labels}}'
{}

$ docker service inspect omt-frontend-31cc8b --format '{{len .PreviousSpec.Labels}}'
9      # the labels still exist in PreviousSpec ⇒ the update removed them

The deployment log only contains the image pull step:

Initializing deployment
Pulling ghcr.io/…:v1.2.45
Login Succeeded
Status: Image is up to date for ghcr.io/…:v1.2.45
✅ Pulling image completed.

(the service update that drops the labels is not logged)

Steps to reproduce
  1. Create an application with sourceType=docker, a registry image and a domain (port 3000, https).
  2. Deploy once and confirm the router works (curl -I https://<domain> → 200, Spec.Labels has the 9 traefik.* entries).
  3. Deploy again from either entry point (webhook or application.deploy).
  4. After the task restarts: Spec.Labels is {}, PreviousSpec.Labels still has them, and every domain of that app returns Traefik's 404.
Impact

CI that deploys on push (or any API automation / UI redeploy) takes the app offline routing-wise until the labels are restored by hand, while the container itself stays up — so health checks and Dokploy's own deployment status still report success.

Workaround we run now

A systemd timer on the Docker host that re-adds the label set whenever traefik.enable is missing from the service (15 s cycle). docker service update --rollback <service> also restores the labels (it reverts the previous spec) but that also rolls the image back to the previous tag.

Context that may or may not matter

Both affected applications were created by duplicating a project (project duplicate --includeServices + application move) on an older Dokploy; in the DB their application.refreshToken was empty (we had to set it) and autoDeploy was false. registryId is null on both (the images are pulled with node-level credentials). Happy to dump the application / domain rows or full specs if that helps.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing the POST /api/deploy/ webhook and POST /api/application.deploy paths through the deployment logic, focusing on the Docker Swarm service update. Reproduce the second deploy and inspect Spec.Labels and PreviousSpec.Labels. Done means redeploying a Docker-image app preserves its traefik.* labels and keeps all configured domains routable.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker, typescript
Domain
backend, devops, infrastructure
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
62/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.