Portainer silently ignores Docker Compose secrets when version is 3.9 or higher
0 reputation · 24 May 2022, 00:40 UTC
0 reputation · 24 May 2022, 00:40 UTC
The goal is to confirm whether secrets defined in a Docker Compose file are actually created when a stack is deployed through Portainer using a Compose version string of 3.9 or newer.
The Portainer interface does not emit a warning about version incompatibility; any diagnostics appear only in the server or agent logs, which creates uncertainty about whether the secrets are omitted silently or simply not reported.
Does Portainer drop the secrets section entirely when the Compose version exceeds 3.8? Are the missing secrets visible only in the agent or server logs, and is there a way to surface this information in the UI? Can a version‑compatibility check be enabled to prevent silent misconfiguration?
35275 reputation · 24 May 2022, 07:42 UTC
Treat this as a deployment-path problem rather than a Compose-spec rule. A top-level secrets: block only becomes a real Docker secret when the stack is deployed to a Swarm cluster through a path that ends in docker stack deploy. If Portainer handles the stack through a Compose CLI interpreter instead, the secrets key is never translated into Swarm secrets, and the UI has no dedicated warning for that. The reported “3.9 or higher” cutoff looks like Portainer-side version gating, not something the Compose file format itself defines. I cannot confirm the exact threshold or that it still exists in your release, so verify against your own instance.
Confirmed on the Docker side: secrets are a Swarm feature. On a standalone Docker Engine, a secrets: block cannot create anything, whatever the version: string says. Separately, docker compose v2 has its own secrets semantics — it mounts files under /run/secrets from local sources and does not create Swarm secrets.
Likely, and worth checking on your version: Portainer selects a Compose interpreter based on the declared version, and for 3.9+ it may route to one that does not support the secrets key. The omission is silent in the UI; any message lives in the Portainer server or agent container logs, and it may be absent entirely.
docker secret lsdocker stack services <stackname>
docker service inspect <stackname>_<service> \
--format '{{json .Spec.TaskTemplate.ContainerSpec.Secrets}}'docker logs portainer 2>&1 | grep -i secret
docker logs portainer_agent 2>&1 | grep -i secretdocker stack deploy -c compose.yml mystack
docker secret lsIf step 5 creates the secret and step 2 does not, the file is fine and Portainer's deploy path is the variable. If step 5 also creates nothing, the problem is the target (not a Swarm manager) or the file itself.
There is no documented toggle that turns unsupported-Compose-feature checks into a blocking error in the UI. Practical substitutes: create secrets out of band and reference them as external, so a missing secret fails the deploy instead of being skipped; or deploy with docker stack deploy and use Portainer only for visibility.
secrets:
db_password:
external: trueIs the Portainer endpoint a Swarm cluster or a standalone Docker host? On standalone, no Compose version will ever create secrets, and the fix is file-based secrets via docker compose or an external secret manager. On Swarm, the fix is the deploy path above.
Because Portainer's handling here has changed across releases, treat this as a conservative draft and re-test after upgrading Portainer or its agent.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.