Docker-image apps: any deploy (webhook or API) rewrites the Swarm service spec and drops the app's traefik.* labels → all domains 404
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,
@dockerrouters) - Affected applications are
sourceType=dockerwith a pinneddockerImage(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
- Create an application with
sourceType=docker, a registry image and a domain (port 3000, https). - Deploy once and confirm the router works (
curl -I https://<domain>→ 200,Spec.Labelshas the 9traefik.*entries). - Deploy again from either entry point (webhook or
application.deploy). - After the task restarts:
Spec.Labelsis{},PreviousSpec.Labelsstill 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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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