Repository navigation
Description
To Reproduce
To Reproduce
Disclosure: the diagnosis, root-cause analysis, suggested fix, and the linked references in this report were produced by Claude Code (Anthropic's CLI coding assistant) — not by me. I observed the symptom on my own deploy, ran the AI to investigate, reviewed the output, and am forwarding it here because the analysis matches what I see and points at concrete files and PRs in this repo. Maintainers should re-verify the code references before acting; I have not independently audited every line cited.
-
In the Dokploy UI, go to Registry and add a private registry with credentials. Dokploy runs
docker logininternally and writes the auth entry to/root/.docker/config.jsonon the host. -
Push at least one image to that registry from outside Dokploy (e.g., from a CI pipeline).
-
In the Dokploy UI, create a new application with:
- Source Type: any source that points to a repo containing a stack file.
- Compose Type:
Stack(Swarm), notCompose.
-
Point the application to a stack file that references the private image, for example:
services: web: image: registry.example.com/my-org/my-app:latest deploy: replicas: 1
-
Click Deploy.
-
After the deploy command finishes, on the host run:
docker stack services <stack-name> docker stack ps <stack-name> --no-trunc
to inspect the task state.
Current vs. Expected behavior
Current vs. Expected behavior
Expected: the manager pulls the image manifest from the registry using the credentials saved by Dokploy's docker login, records the digest in the service spec, propagates valid auth to workers via --with-registry-auth, and the service tasks reach running.
Actual: the deploy log prints
image registry.example.com/my-org/my-app:latest could not be accessed
on a registry to record its digest. Each node will access
registry.example.com/my-org/my-app:latest independently, possibly
leading to different nodes running different versions of the image.
Docker Compose Deployed: ✅
docker stack services shows 0/1 replicas, and docker stack ps --no-trunc reveals the tasks failing to pull (No such image / auth errors) even though:
- The registry is reachable from the host.
- The credentials in Dokploy → Registry are correct.
/root/.docker/config.jsonon the host contains a valid entry for the registry.- Switching the same application to Compose type (same image, same registry, same credentials) deploys and runs successfully.
Root cause
In packages/server/src/utils/builders/compose.ts, the deploy command is wrapped in:
env -i PATH="$PATH" ${exportEnvCommand} docker ${command.split(" ").join(" ")}env -i strips all environment variables, including HOME. Only PATH and the project-scoped vars produced by exportEnvCommand survive — HOME is not re-exported.
With an empty HOME, the Docker CLI expands ~/.docker/config.json to /.docker/config.json instead of /root/.docker/config.json. That path does not exist, so the CLI silently falls back to anonymous access. The manager cannot resolve the image digest, and the auth payload that --with-registry-auth ships to workers is empty.
This bug is invisible in Compose mode because Dokploy writes DOCKER_CONFIG=/root/.docker into the project's .env file, which docker compose reads. docker stack deploy does not consume the project .env for its own auth resolution, so the same workaround does not apply.
The env -i was introduced by #3062. --with-registry-auth was later added to the stack deploy command by #3341, but the interaction with #3062 was not caught.
Provide environment information
## Provide environment information
Operating System:
OS: <fill in — e.g., Ubuntu 24.04>
Arch: <fill in — e.g., x86_64>
Dokploy version: <fill in — check the UI footer>
VPS Provider: <fill in>
What applications/services are you trying to deploy?
A multi-service Node.js stack (Fastify API + Next.js web + cron worker + one-shot Prisma migration) pulled from a self-hosted Zot registry behind Traefik with TLS.Which area(s) are affected? (Select all that apply)
Docker Compose, Docker
Are you deploying the applications where Dokploy is installed or on a remote server?
Same server where Dokploy is installed
Additional context
Additional context
Suggested fix
Preserve HOME (and optionally DOCKER_CONFIG) across the env -i boundary so the Docker CLI can locate ~/.docker/config.json:
- env -i PATH="$PATH" ${exportEnvCommand} docker ${command.split(" ").join(" ")}
+ env -i HOME="$HOME" DOCKER_CONFIG="${DOCKER_CONFIG:-$HOME/.docker}" PATH="$PATH" ${exportEnvCommand} docker ${command.split(" ").join(" ")}This single-line change:
- Restores correct expansion of
~/.docker/config.jsonfor the Docker CLI. - Honors an explicit
DOCKER_CONFIGoverride if set by the operator. - Has no side effects on Compose mode (the existing
.envinjection ofDOCKER_CONFIGkeeps working).
Workaround (for users hitting this today)
On the Swarm manager host:
mkdir -p /.docker
cp /root/.docker/config.json /.docker/config.jsonBecause HOME is empty inside env -i, ~ resolves to / and the CLI now finds /.docker/config.json. After this, redeploy from the Dokploy UI — docker stack deploy --with-registry-auth will pick up the credentials, record the digest, and propagate valid auth to workers. This is a single-node workaround; on a multi-node cluster the credentials would need to exist on every worker, or --with-registry-auth needs to function correctly (which is what the fix above restores).
Related issues and PRs
- #3311 — Docker Stack deployment from private GitHub Repo (closed, inactivity) — same external symptom (Compose works, Stack fails with a private registry; only succeeds after running
docker loginmanually). The root cause was never diagnosed and the issue was closed for inactivity. - #3062 — fix: update Docker command execution to use a clean environment (merged) — introduced the
env -i PATH="$PATH" ...wrapper. The intent was to prevent env vars leaking; the side effect of strippingHOMEwas not flagged. - #3341 — fix: pass registry auth to stack deploy (merged) — added
--with-registry-authto the stack deploy command. Worked in the author's environment because their/root/.docker/config.jsonhappened to be reachable, but did not account forHOMEalready being stripped by fix: update Docker command execution to use a clean environment #3062. - #2759 — Registry Credentials Not Applied to Remote VPS (open) — adjacent symptom (credentials not propagated to remote VPS). Different root cause, but in the same area of the code.
- #3886 — Docker login/logout on all servers for registry operations (open) — adjacent (login only runs on one node, not all).
Code references
packages/server/src/utils/builders/compose.ts— the bash command that runsdocker stack deploy(whereenv -ilives).packages/server/src/services/registry.ts— where Dokploy'sdocker loginruns and writes credentials to/root/.docker/config.json.
Will you send a PR to fix it?
No
Activity
dosubot commentedon May 13, 2026
Hi @leogomide! I'm Dosu and I’m helping the dokploy team.
I can confirm this analysis is accurate. The
env -iwrapper on line 57 ofpackages/server/src/utils/builders/compose.tsonly preservesPATHand the export env command variables —HOMEis not included [1]:And the stack deploy command on line 93 does include
--with-registry-auth[2]:No existing PR has addressed preserving
HOMEin theenv -iwrapper. The PRs that touched this area — #3062 [3], #3071 [4], and #3341 [5] — improved environment handling and added--with-registry-authbut didn't account for the interaction betweenenv -istrippingHOMEand Docker needing it to resolve~/.docker/config.json.The suggested fix of adding
HOME="$HOME"to theenv -iline looks correct and minimal. AddingDOCKER_CONFIGas a fallback is a nice bonus for operators who override the config location, thoughHOMEalone should be sufficient for the default setup.To reply, just mention @dosu.
Docs are dead. Just use Dosu.
fix: preserve HOME in compose deploy so --with-registry-auth can read…
🚀 Release v0.29.6 (#4514)
🚀 Release v0.29.8 (#4562)
chore(release): 0.37.0 [skip ci]
fix: preserve HOME in compose deploy so --with-registry-auth can read…