Skip to content

Instantly share code, notes, and snippets.

@gorshkov-leonid
Last active April 2, 2025 10:16
Show Gist options
  • Save gorshkov-leonid/946e4701c100c668492b77153a443af8 to your computer and use it in GitHub Desktop.
Save gorshkov-leonid/946e4701c100c668492b77153a443af8 to your computer and use it in GitHub Desktop.
Docker In Windows (Final)

See final versions without trash here

Docker in Windows without Docker Desktop

❤️‍🔥 Install docker client in Windows

  • Download necessary version of docker binaries from https://docs.docker.com/engine/install/binaries/ and extract archive to c:/Program Files, for example, using script in powershell. Run powershell as Administrator and call:

    Expand-Archive .\docker-20.10.9.zip -DestianationPath $Env:ProgramFiles  

    Files docker.exe and dockerd.exe will be here c:/Program Files/docker/.

    We need only docker.exe and do not need dockerd.exe because it can start only Windows containers. To check it you can try to call as Admin dockerd.exe and then docker.exe pull ubuntu. Expected result: no matching manifest for windows/amd64 10.0.19043 in the manifest list entries

  • Add path c:/Program Files/docker to environment variable PATH. It could be done with this powershell script:

    [Environment]::SetEnvironmentVariable("Path",$env:Path + ";c:/Program Files/docker", "Machine")

❤️‍🔥 Install Docker Daemon in WSL

  • Install docker under Ubuntu WSL using these instructions https://docs.docker.com/engine/install/ubuntu/

  • To provide ability to call docker in WSL without sudo add current user to docker group

    sudo groupadd docker
    sudo usermod -aG docker $USER
  • Configure dockerd to run over http with access from Windows

    ⤵️ Edit /etc/profile

    function rundocker(){
      ## Use this variant in case when `localhostForwarding` in `/etc/wsl.conf` is unset or equal to `false`
      #DOCKER_HOST=`ifconfig eth0 | grep -E "inet ([0-9]{1,3}.){3}[0-9]{1,3}" | head -1 | awk '{ print $2 }'`
      DOCKER_HOST=localhost
      WIN_CLIENT="/mnt/c/Program Files/docker/docker.exe"
      "$WIN_CLIENT" context rm -f wsl > /dev/null
      "$WIN_CLIENT" context create wsl --description "dockerd in WSL" --docker "host=tcp://$DOCKER_HOST:2375"
      "$WIN_CLIENT" context use wsl
      sudo dockerd -H $DOCKER_HOST -H "unix:///var/run/docker.sock" --tls=false
    }
    export -f rundocker
    Details...

    ⚠️ Be aware of this warnings:

    Binding to IP address without --tlsverify is insecure and gives root access on this machine to everyone who has access to your network.  host="tcp://172.27.117.140:2375"
    Binding to an IP address, even on localhost, can also give access to scripts run in a browser. Be safe out there!  host="tcp://172.27.117.140:2375"
    

    ⤵️ Run docker daemon on Windows startup using Task Scheduler (taskschd.msc)

    $task = New-ScheduledTaskAction -Execute "C:\Windows\System32\wsl.exe" -Argument '-u root bash -c "(source /etc/profile && rundocker &) && sleep 10"'
    $trigger = New-ScheduledTaskTrigger -AtLogon
    $settings = New-ScheduledTaskSettingsSet -DontStopIfGoingOnBatteries -AllowStartIfOnBatteries
    Register-ScheduledTask RunDocker -Action $task -Trigger $trigger -Settings $settings

    ⤵️ To stop docker daemon manually

    sudo kill $(ps faux | grep 'dockerd' | grep -vw grep | awk '{ print $2 }')

❤️‍🔥 Docker Compose

sudo apt-get install -y python3 python3-pip
pip3 install --user docker-compose

⚠️ Do not forget to set variable DOCKER_HOST in ~/.bashrc if it has not still done.

export DOCKER_HOST=tcp://localhost:2375

⚠️ On error TypeError: load_config() got an unexpected keyword argument 'config_dict' try to call scripts:

pip3 uninstall docker-compose
pip3 uninstall docker-py docker
pip3 install --user -U docker-compose

See also link1, link2, link3

See Setting Up Docker for Windows and WSL to Work Flawlessly

☢️ Problem with host.docker.internal

I caught error Error: net::ERR_CONNECTION_REFUSED at http://host.docker.internal:6006?path=... with docker-chromium having run under jet-puppeteer-docker in Jetbrains Idea (only there). The only way to fix it was found:

  • Install Docker Desktop and clone folder c:\Program Files\Docker as c:\Program Files\Docker_. After that Docker Desktop can be removed.
  • Then make steps above to unpack binaries. Then copy with a replace files docker.exe and com.docker.cli.exe from c:\Program Files\Docker_\Docker\resources\bin\ to c:\Program Files\Docker.
  • I do not know why it is so. Despite docker.exe is just client to dockerd in WSL, but it makes some difference. When we use not-patched version of docker.exe then /etc/hosts does not contains needed alias. But when we use patched version of docker.exe from Docker Desktop (with required com.docker.cli.exe) then it gets OK. I suggested that a problem is hidden in difference of versions and checked it. Probably, Nope.
    • Docker 20.10.10, build b485636 from Docker Desktop
    • Docker 20.10.9, build c2ea9bc from binaries
    • Docker 20.10.10, build b485636 from binaries
  • At the same time do not touch docker-compose.exe, leave original version

K8s

   kubectl config set-cluster xyz --insecure-skip-tls-verify --server=https://api.${K8S_HOST}:${K8S_PORT}
   kubectl config set-credentials xyz-admin --token=${K8S_USER_TOKEN}
   kubectl config set-context xyz --cluster=xyz --user=xyz-admin
   kubectl config use-context xyz
  • Use Intellij Idea plugin to access
@gorshkov-leonid
Copy link
Author

gorshkov-leonid commented Jan 29, 2023

Ubuntu 22.04

WARN[2023-01-29T20:53:30.973064814+04:00] grpc: addrConn.createTransport failed to connect to {unix:///var/run/docker/containerd/containerd.sock  <nil> 0 <nil>}. Err :connection error: desc = "transport: Error while dialing dial unix:///var/run/docker/containerd/containerd.sock: timeout". Reconnecting...  module=grpc
failed to start daemon: Error initializing network controller: error obtaining controller instance: unable to add return rule in DOCKER-ISOLATION-STAGE-1 chain:  (iptables failed: iptables --wait -A DOCKER-ISOLATION-STAGE-1 -j RETURN: iptables v1.8.7 (nf_tables):  RULE_APPEND failed (No such file or directory): rule in chain DOCKER-ISOLATION-STAGE-1

microsoft/WSL#6655 (comment)

Solution:

sudo update-alternatives --set iptables /usr/sbin/iptables-legacy
sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy

@gorshkov-leonid
Copy link
Author

gorshkov-leonid commented Apr 3, 2024

In case of enabled systemd in /etc/wsl.conf:

[boot]
systemd=true

you can start docker via systemd.

Ususally systemd unit is cerated during docker installation ut I leave here my variant:

/etc/systemd/system/docker.service

systemctl edit docker.service --full

[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service containerd.service
Wants=network-online.target
Requires=docker.socket containerd.service

[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
# ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecStart=/usr/bin/dockerd  -H localhost -H "unix:///var/run/docker.sock" --tls=false
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always

# Note that StartLimit* options were moved from "Service" to "Unit" in systemd 229.
# Both the old, and new location are accepted by systemd 229 and up, so using the old location
# to make them work for either version of systemd.
StartLimitBurst=3

# Note that StartLimitInterval was renamed to StartLimitIntervalSec in systemd 230.
# Both the old, and new name are accepted by systemd 230 and up, so using the old name to make
# this option work for either version of systemd.
StartLimitInterval=60s

# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity

# Comment TasksMax if your systemd version does not support it.
# Only systemd 226 and above support this option.
TasksMax=infinity

# set delegate yes so that systemd does not reset the cgroups of docker containers
Delegate=yes

# kill only the docker process, not all processes in the cgroup
KillMode=process
OOMScoreAdjust=-500

[Install]
WantedBy=multi-user.target

then you can not to rundockerd in the script:

#/etc/profile
function rundocker(){
  #DOCKER_HOST=`ifconfig eth0 | grep -E "inet ([0-9]{1,3}.){3}[0-9]{1,3}" | head -1 | awk '{ print $2 }'`
  DOCKER_HOST=localhost
  WIN_CLIENT="/mnt/c/Program Files/docker/docker.exe"
  "$WIN_CLIENT" context rm -f wsl > /dev/null
  "$WIN_CLIENT" context create wsl --description "dockerd in WSL" --docker "host=tcp://$DOCKER_HOST:2375"
  "$WIN_CLIENT" context use wsl
}
export -f rundocker

Change ExecStart section in /etc/systemd/system/docker.service:

  • Call systemctl edit docker.service --full
  • Comment ExecStart section and add another one: ExecStart=/usr/bin/dockerd -H localhost -H "unix:///var/run/docker.sock" --tls=false
  • Restart service: sudo systemctl restart docker.service
  • Reload systemctl daemon: sudo systemctl daemon-reload

After that docker will be accessible from windows.

@gorshkov-leonid
Copy link
Author

gorshkov-leonid commented Apr 3, 2024

To disable docker installed by the way described above:

  • disable task RunDocker in scheduler
  • disable systemctl service docker.service:
       # check:
       systemctl list-unit-files | grep -i docker
    
       #disable
       sudo systemctl stop docker.service
       sudo systemctl stop docker.socket
       sudo systemctl disable docker.service
       sudo systemctl disable docker.socket
    
       sudo systemctl stop snap-docker-2915.mount
       sudo systemctl stop snap.docker.dockerd.service
       sudo systemctl stop snap.docker.nvidia-container-toolkit.service
       sudo systemctl disable snap-docker-2915.mount
       sudo systemctl disable snap.docker.dockerd.service
       sudo systemctl disable snap.docker.nvidia-container-toolkit.service
  • remove socker dontect in windows "c:/Program Files/docker/docker.exe" context rm -f wsl

@gorshkov-leonid
Copy link
Author

Enable:

   sudo systemctl enable docker.service
   sudo systemctl enable docker.socket
   sudo systemctl enable snap-docker-2915.mount
   sudo systemctl enable snap.docker.dockerd.service
   sudo systemctl enable snap.docker.nvidia-container-toolkit.service
   
   sudo systemctl start docker.service
   sudo systemctl start docker.socket
   sudo systemctl start snap-docker-2915.mount
   sudo systemctl start snap.docker.dockerd.service
   sudo systemctl start snap.docker.nvidia-container-toolkit.service

@gorshkov-leonid
Copy link
Author

gorshkov-leonid commented Apr 17, 2024

Access podman from other wsl distros: containers/podman#16130 (comment) 👍
Pull request: containers/podman#19705
Duplicates:
containers/podman#16660 👍
containers/podman#15190

wsl -d podman-machine-default
sudo mount --bind /var/run/docker.sock /mnt/wsl/docker.sock
chmod 777 /mnt/wsl/podman.sock
exit


ls /mnt/wsl/podman.sock
export DOCKER_HOST=unix:///mnt/wsl/docker.sock

If docker was not found, create bat to alias podman->docker or download windows binaaries:
https://podman-desktop.io/docs/migrating-from-docker/emulating-docker-cli-with-podman
https://github.com/Shopify/docker/blob/master/docs/installation/binaries.md#get-the-windows-binary

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment