docker stack deploy Fails When Run From cmd.exe on Windows with CLI v23+ · Issue #4078 · docker/cli (original) (raw)
Description
Trying to deploy a stack (docker stack deploy
) when using version 23+ of the Docker CLI under a process started by Windows cmd.exe
causes an error message similar to:
unexpected environment "=::=::\\"
This also affects docker stack config
.
My System
The failure happens in Docker CLI 23.0.0 and 23.0.1. I'm using Windows 10 Enterprise 21H2 19044.2604.
The Key Part
cmd.exe
has to be involved in starting the docker
process in some manner. So you could run cmd.exe
and then docker
. Or cmd.exe
and then pwsh.exe
and then docker
.
The Relevant Code
This appears to be the relevant code. Environment variables are read and iterated through. If one is found with a blank name/key, the error message is printed and docker aborts.
Why Does This Happen
The Old New Thing has the best explanation of this. cmd.exe
basically keeps special environment variables with blank names to support old MS-DOS functionality. These are the environment variables that Docker stumbles over.
Stack Overflow question about this. Here you'll see talk of the =::=::\\
value that I commonly see.
Reproduce
- Be using the Docker CLI version 23.0.0 or 23.0.1 on Windows.
- Have a simple stack file named
Stack.yml
. See example below. - Start a Windows command prompt (
cmd.exe
) - This is key! - Run this:
docker stack deploy -c Stack.yml Stack
- The output is:
unexpected environment "=::=::\\"
Example Stack File:
services:
hello:
image: hello-world:latest
Expected behavior
The stack should deploy without error.
For comparison purposes, you can follow these steps to see the stack deploy correctly:
- Be using the Docker CLI version 23.0.0 or 23.0.1 on Windows.
- Have a simple stack file named
Stack.yml
. See example in the Reproduce section. - Start a PowerShell 7 session without going through
cmd.exe
. The reliable way I've found to do this is search forpwsh.exe
from the Start menu. Using icons in the Start menu doesn't seem to work all the time. - Run this:
docker stack deploy -c Stack.yml Stack
- The output is:
Creating network Stack_default
Creating service Stack_hello
docker version
C:\Users\twinter>docker version Client: Version: 23.0.1 API version: 1.42 Go version: go1.19.5 Git commit: a5ee5b1 Built: Thu Feb 9 19:50:24 2023 OS/Arch: windows/amd64 Context: default
Server: Docker Engine - Community Engine: Version: 23.0.1 API version: 1.42 (minimum version 1.12) Go version: go1.19.5 Git commit: bc3805a Built: Thu Feb 9 19:46:47 2023 OS/Arch: linux/amd64 Experimental: false containerd: Version: 1.6.18 GitCommit: 2456e983eb9e37e47538f59ea18f2043c9a73640 runc: Version: 1.1.4 GitCommit: v1.1.4-0-g5fd4c4d docker-init: Version: 0.19.0 GitCommit: de40ad0
docker info
Client: Context: default Debug Mode: false Plugins: sbom: View the packaged-based Software Bill Of Materials (SBOM) for an image (Anchore Inc.) Version: 0.6.1 Path: C:\Users\twinter.docker\cli-plugins\docker-sbom.exe
Server: Containers: 25 Running: 0 Paused: 0 Stopped: 25 Images: 17 Server Version: 23.0.1 Storage Driver: overlay2 Backing Filesystem: xfs Supports d_type: true Using metacopy: false Native Overlay Diff: true userxattr: false Logging Driver: json-file Cgroup Driver: cgroupfs Cgroup Version: 1 Plugins: Volume: local Network: bridge host ipvlan macvlan null overlay Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog Swarm: active NodeID: 1bis6jp8bw0eg3x73wfrq1px5 Is Manager: true ClusterID: exugqkpkx2cn5bp38wcw73dxo Managers: 1 Nodes: 1 Default Address Pool: 10.0.0.0/8 SubnetSize: 24 Data Path Port: 4789 Orchestration: Task History Retention Limit: 5 Raft: Snapshot Interval: 10000 Number of Old Snapshots to Retain: 0 Heartbeat Tick: 1 Election Tick: 10 Dispatcher: Heartbeat Period: 5 seconds CA Configuration: Expiry Duration: 3 months Force Rotate: 0 Autolock Managers: false Root Rotation In Progress: false Node Address: 10.2.96.83 Manager Addresses: 10.2.96.83:2377 Runtimes: io.containerd.runc.v2 runc Default Runtime: runc Init Binary: docker-init containerd version: 2456e983eb9e37e47538f59ea18f2043c9a73640 runc version: v1.1.4-0-g5fd4c4d init version: de40ad0 Security Options: seccomp Profile: builtin Kernel Version: 4.18.0-425.3.1.el8.x86_64 Operating System: Red Hat Enterprise Linux 8.7 (Ootpa) OSType: linux Architecture: x86_64 CPUs: 3 Total Memory: 7.071GiB Name: PRD-VIRT-RHL-56.AD.VERVEINDUSTRIAL.COM ID: IPGK:JLNH:EKXO:NZLH:O2O4:GQC5:PE7C:NYBC:BKQA:HNR2:Q36F:WCJ5 Docker Root Dir: /var/lib/docker Debug Mode: false Registry: https://index.docker.io/v1/ Experimental: false Insecure Registries: 127.0.0.0/8 Live Restore Enabled: false
Additional Info
Checking the Environment Like Docker CLI
Below is a simple golang program that uses the Docker CLI code to show you the environment variables that are failing Docker.
package main
import (
"fmt"
"os"
"strings"
)
func main() {
buildEnvironment(os.Environ())
}
func buildEnvironment(env []string) (map[string]string, error) {
result := make(map[string]string, len(env))
for _, s := range env {
k, v, ok := strings.Cut(s, "=")
if !ok || k == "" {
fmt.Println("unexpected environment:")
fmt.Println(" key: ", k)
fmt.Println(" value:", v)
fmt.Println()
}
// value may be set, but empty if "s" is like "K=", not "K".
result[k] = v
}
return result, nil
}