Skip to content

Instantly share code, notes, and snippets.

@SeanSobey
Last active April 7, 2024 18:46
Show Gist options
  • Save SeanSobey/344edd228922ffd4266ae7d451421ab6 to your computer and use it in GitHub Desktop.
Save SeanSobey/344edd228922ffd4266ae7d451421ab6 to your computer and use it in GitHub Desktop.
Portainer Setup on Windows 10

Portainer on Windows 10

Here I have 2 methods for running portainer on windows, a quick, preferred method only requiring a fairly recent version of docker, or a more complicated method to try if that does not work.

Using host.docker.internal

This setup will let you run Portainer on windows by using the host.docker.internal endpoint (docker.for.win.localhost is depricated since docker version 3.2.1, but older versions may use this instead).

Please note:

  • This will expose your docker API, without TLS, publicly from your machine.
  • For more advanced config see the portainer docs.

Step 1 Enable docker without TLS

Docker settings -> General -> Expose docker daemon on tcp://...

Step 2 Run Portainer Image

The only trick here is to use this endpoint: tcp://host.docker.internal:2375 (tcp://docker.for.win.localhost:2375 is depricated).

Create portainer volume

Powsershell (admin):

docker volume create portainer_data

Create portainer container

With No Auth
docker run -d -p 3040:9000 --name portainer --restart=always -v portainer_data:/data portainer/portainer --no-auth -H tcp://host.docker.internal:2375
With Auth
docker run -d -p 3040:9000 --name portainer --restart=always -v portainer_data:/data portainer/portainer -H tcp://host.docker.internal:2375

Go to http://localhost:3040

To remove and revert all changes

Powsershell (admin):

docker stop portainer

docker rm portainer

docker rmi portainer/portainer

docker volume rm portainer_data

Using a loopback address (Fallback method)

This setup will let you run Portainer on windows by using a loopback address.

Please note:

  • Working with (current) Docker version 2.1.0.1, Windows 10 Build 18362.
  • YOU NEED TO BE ON LINUX CONTAINERS, this will not work on windows containers.
  • This will expose your docker API, without TLS, publicly from your machine.
  • For more advanced config see the portainer docs.

Step 1 Enable docker without TLS

Docker settings -> General -> Expose docker daemon on tcp://...

Find your docker API address

ipconfig -> Ethernet adapter vEthernet (DockerNAT): -> IPv4 Address -> eg: 10.0.75.1

This will be referred to as $DockerAddress.

Step 2 Create Looback Address

Powsershell (admin):

netsh interface portproxy add v4tov4 listenaddress=$DockerAddress listenport=2375 connectaddress=127.0.0.1 connectport=2375

Step 3 Allow Loopback through Firewall

Powsershell (admin):

netsh advfirewall firewall add rule name="Docker" dir=in action=allow protocol=TCP localport=2375 enable=yes profile=domain,private,public

OR, Manual version, create new firewall rule:

Firewall inbound rule:
	Rule Type: Port
	Protocol and Ports: TCP, 2375
	Action: Allow
	Profile: Domain, Private & Public
	Name: Docker

Edit Rule
	Scope, Remote IP address: 127.0.0.1

Step 4 Test Loopback

If the above steps were done correctly you should be able to see the docker API exposed on http://127.0.0.1:2375/ and http://10.0.75.1:2375/ (will just return a {"message":"page not found"} response).

Step 5 Run Portainer Image

Create portainer volume

Powsershell (admin):

docker volume create portainer_data

Create portainer container

With Auth
docker run -d -p 3040:9000 --name portainer --restart=always -v portainer_data:/data portainer/portainer

Go to http://localhost:3040 and add your endpoint (endpoint is: $DockerAddress:2375)

With No Auth

Powsershell (admin):

docker run -d -p 3040:9000 --name portainer --restart=always -v portainer_data:/data portainer/portainer --no-auth -H tcp://$DockerAddress:2375

Go to http://localhost:3040

To remove and revert all changes

Powsershell (admin):

docker stop portainer

docker rm portainer

docker rmi portainer/portainer

docker volume rm portainer_data

netsh interface portproxy reset

netsh advfirewall firewall delete rule name="Docker"
@SeanSobey
Copy link
Author

Updated method using tcp socket, no loopback required: http://blog.airdesk.com/2017/10/windows-containers-portainer-gui.html

@SeanSobey
Copy link
Author

New-NetFirewallRule -DisplayName "Portainer" -Direction Inbound -LocalPort 2375 -Protocol TCP -Action Allow -Profile Any -RemoteAddress 127.0.0.1

Remove-NetFirewallRule -DisplayName "Portainer"

@SeanSobey
Copy link
Author

Use original method!

@sylvanaar
Copy link

Host endpoint is now: docker.for.win.localhost:2375

@benrr101
Copy link

Holy crap, thank you for this!

@dovry
Copy link

dovry commented Dec 10, 2018

Amazing, the Portainer docs don't even work.
Thanks a lot!

  • Worth mentioning for anyone from the future..
    YOU NEED TO BE ON LINUX CONTAINERS, this will not work on windows containers.

@petrosmm
Copy link

Host endpoint is now: docker.for.win.localhost:2375

I spent 3 days on this issue, thank you!!!!!!!!!!!!!

@Mortinke
Copy link

Mortinke commented Nov 4, 2019

Works for me without Loopback Address and Firewall modification:
docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer -H tcp://docker.for.win.localhost:2375

@SeanSobey
Copy link
Author

SeanSobey commented Nov 4, 2019

Works for me without Loopback Address and Firewall modification:
docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer -H tcp://docker.for.win.localhost:2375

@Mortinke Thanks!! You can also remove the volume command, eg docker run -d -p 9000:9000 portainer/portainer -H tcp://docker.for.win.localhost:2375.

Updated the gist 👍

@memo-oa
Copy link

memo-oa commented Mar 27, 2020

Hey Sean! thanks for this info! it was working for me, but today after starting the portainer again suddenly it goes to restarting status forever, looking at the logs I'm getting the next error again and again.

 Templates already registered inside the database. Skipping template import.
2020/03/22 12:30:27 Get http://docker.for.win.localhost:2375/_ping: dial tcp 192.168.65.2:2375: connect: connection refused

do you know how to solve this?

@user18x
Copy link

user18x commented Apr 30, 2020

I don't think this will work because of
docker volume create portainer_data
So portainer_data:/data isn't a windows folder, it's linux!

Read section windows here:
https://www.portainer.io/documentation/quick-start/
And i quote:

Example for Linux containers:
C:\ProgramData\Portainer:/data

Example for native Windows containers:
C:\ProgramData\Portainer:C:\data

PS: I'm new in docker! :-P

@SeanSobey
Copy link
Author

SeanSobey commented Apr 30, 2020

I don't think this will work because of
docker volume create portainer_data
So portainer_data:/data isn't a windows folder, it's linux!

Read section windows here:
https://www.portainer.io/documentation/quick-start/
And i quote:

Example for Linux containers:
C:\ProgramData\Portainer:/data
Example for native Windows containers:
C:\ProgramData\Portainer:C:\data

PS: I'm new in docker! :-P

Hi @user18x! This works by creating a named volume, see here

@SeanSobey
Copy link
Author

Hey Sean! thanks for this info! it was working for me, but today after starting the portainer again suddenly it goes to restarting status forever, looking at the logs I'm getting the next error again and again.

 Templates already registered inside the database. Skipping template import.
2020/03/22 12:30:27 Get http://docker.for.win.localhost:2375/_ping: dial tcp 192.168.65.2:2375: connect: connection refused

do you know how to solve this?

Hi @memo-oa! Did you try the fallback method

@oonqt
Copy link

oonqt commented May 6, 2020

Thank you for this! The docker documentation is so shit (as evident by the ratings on the bottom of most documentation pages)

@NeverMoes
Copy link

nice!

@edwinhuish
Copy link

unknown shorthand flag: 'H' in -H

I'm using docker desktop for win10, version: 2.3.0.3 (45519) .... But -H is not work for me. WHY?

PS C:\WINDOWS\system32> docker run -d -p 9000:9000 --name portainer --restart unless-stopped -v D:\docker\portainer\data:/data -v D:\docker\portainer\www:/public -H tcp://docker.for.win.localhost:2375 portainer/portainer
unknown shorthand flag: 'H' in -H
See 'docker run --help'.
PS C:\WINDOWS\system32> docker run --help

Usage:  docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

Run a command in a new container

Options:
      --add-host list                  Add a custom host-to-IP mapping
                                       (host:ip)
  -a, --attach list                    Attach to STDIN, STDOUT or STDERR
      --blkio-weight uint16            Block IO (relative weight),
                                       between 10 and 1000, or 0 to
                                       disable (default 0)
      --blkio-weight-device list       Block IO weight (relative device
                                       weight) (default [])
      --cap-add list                   Add Linux capabilities
      --cap-drop list                  Drop Linux capabilities
      --cgroup-parent string           Optional parent cgroup for the
                                       container
      --cidfile string                 Write the container ID to the file
      --cpu-period int                 Limit CPU CFS (Completely Fair
                                       Scheduler) period
      --cpu-quota int                  Limit CPU CFS (Completely Fair
                                       Scheduler) quota
      --cpu-rt-period int              Limit CPU real-time period in
                                       microseconds
      --cpu-rt-runtime int             Limit CPU real-time runtime in
                                       microseconds
  -c, --cpu-shares int                 CPU shares (relative weight)
      --cpus decimal                   Number of CPUs
      --cpuset-cpus string             CPUs in which to allow execution
                                       (0-3, 0,1)
      --cpuset-mems string             MEMs in which to allow execution
                                       (0-3, 0,1)
  -d, --detach                         Run container in background and
                                       print container ID
      --detach-keys string             Override the key sequence for
                                       detaching a container
      --device list                    Add a host device to the container
      --device-cgroup-rule list        Add a rule to the cgroup allowed
                                       devices list
      --device-read-bps list           Limit read rate (bytes per second)
                                       from a device (default [])
      --device-read-iops list          Limit read rate (IO per second)
                                       from a device (default [])
      --device-write-bps list          Limit write rate (bytes per
                                       second) to a device (default [])
      --device-write-iops list         Limit write rate (IO per second)
                                       to a device (default [])
      --disable-content-trust          Skip image verification (default true)
      --dns list                       Set custom DNS servers
      --dns-option list                Set DNS options
      --dns-search list                Set custom DNS search domains
      --domainname string              Container NIS domain name
      --entrypoint string              Overwrite the default ENTRYPOINT
                                       of the image
  -e, --env list                       Set environment variables
      --env-file list                  Read in a file of environment variables
      --expose list                    Expose a port or a range of ports
      --gpus gpu-request               GPU devices to add to the
                                       container ('all' to pass all GPUs)
      --group-add list                 Add additional groups to join
      --health-cmd string              Command to run to check health
      --health-interval duration       Time between running the check
                                       (ms|s|m|h) (default 0s)
      --health-retries int             Consecutive failures needed to
                                       report unhealthy
      --health-start-period duration   Start period for the container to
                                       initialize before starting
                                       health-retries countdown
                                       (ms|s|m|h) (default 0s)
      --health-timeout duration        Maximum time to allow one check to
                                       run (ms|s|m|h) (default 0s)
      --help                           Print usage
  -h, --hostname string                Container host name
      --init                           Run an init inside the container
                                       that forwards signals and reaps
                                       processes
  -i, --interactive                    Keep STDIN open even if not attached
      --ip string                      IPv4 address (e.g., 172.30.100.104)
      --ip6 string                     IPv6 address (e.g., 2001:db8::33)
      --ipc string                     IPC mode to use
      --isolation string               Container isolation technology
      --kernel-memory bytes            Kernel memory limit
  -l, --label list                     Set meta data on a container
      --label-file list                Read in a line delimited file of labels
      --link list                      Add link to another container
      --link-local-ip list             Container IPv4/IPv6 link-local
                                       addresses
      --log-driver string              Logging driver for the container
      --log-opt list                   Log driver options
      --mac-address string             Container MAC address (e.g.,
                                       92:d0:c6:0a:29:33)
  -m, --memory bytes                   Memory limit
      --memory-reservation bytes       Memory soft limit
      --memory-swap bytes              Swap limit equal to memory plus
                                       swap: '-1' to enable unlimited swap
      --memory-swappiness int          Tune container memory swappiness
                                       (0 to 100) (default -1)
      --mount mount                    Attach a filesystem mount to the
                                       container
      --name string                    Assign a name to the container
      --network network                Connect a container to a network
      --network-alias list             Add network-scoped alias for the
                                       container
      --no-healthcheck                 Disable any container-specified
                                       HEALTHCHECK
      --oom-kill-disable               Disable OOM Killer
      --oom-score-adj int              Tune host's OOM preferences (-1000
                                       to 1000)
      --pid string                     PID namespace to use
      --pids-limit int                 Tune container pids limit (set -1
                                       for unlimited)
      --privileged                     Give extended privileges to this
                                       container
  -p, --publish list                   Publish a container's port(s) to
                                       the host
  -P, --publish-all                    Publish all exposed ports to
                                       random ports
      --read-only                      Mount the container's root
                                       filesystem as read only
      --restart string                 Restart policy to apply when a
                                       container exits (default "no")
      --rm                             Automatically remove the container
                                       when it exits
      --runtime string                 Runtime to use for this container
      --security-opt list              Security Options
      --shm-size bytes                 Size of /dev/shm
      --sig-proxy                      Proxy received signals to the
                                       process (default true)
      --stop-signal string             Signal to stop a container
                                       (default "15")
      --stop-timeout int               Timeout (in seconds) to stop a
                                       container
      --storage-opt list               Storage driver options for the
                                       container
      --sysctl map                     Sysctl options (default map[])
      --tmpfs list                     Mount a tmpfs directory
  -t, --tty                            Allocate a pseudo-TTY
      --ulimit ulimit                  Ulimit options (default [])
  -u, --user string                    Username or UID (format:
                                       <name|uid>[:<group|gid>])
      --userns string                  User namespace to use
      --uts string                     UTS namespace to use
  -v, --volume list                    Bind mount a volume
      --volume-driver string           Optional volume driver for the
                                       container
      --volumes-from list              Mount volumes from the specified
                                       container(s)
  -w, --workdir string                 Working directory inside the container

@SeanSobey
Copy link
Author

SeanSobey commented Jun 9, 2020

@edwinhuish -H is a portainer parameter not a docker one and should go after the docker command:

docker run ... portainer/portainer -H tcp://docker.for.win.localhost:2375

not

docker run -H tcp://docker.for.win.localhost:2375 ... portainer/portainer

Eg your example

docker run -d -p 9000:9000 --name portainer --restart unless-stopped -v D:\docker\portainer\data:/data -v D:\docker\portainer\www:/public portainer/portainer -H tcp://docker.for.win.localhost:2375

@edwinhuish
Copy link

@SeanSobey Thank you.

But I found another way as below:

version: "3"
services:
  portainer:
    image: portainer/portainer:latest
    container_name: portainer
    network_mode: "bridge"
    restart: unless-stopped
    ports:
      - 9000:9000
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - D:\docker\portainer\data:/data

The diffrent is /var/run/docker.sock:/var/run/docker.sock, it works fine for me.

You could use the docker run way, but I prefer docker-compose way

@Th0masAAnderson
Copy link

Hello togehter,
just a stupid question from a newbie to Docker and Portainer. I have to take over an already existing, installed but not configured working installation from Portainer on Windows Server 2019. How can I change the working, data and or, most important, the image directory without installing all new? I can't find a solution on Google since days.

Thanks in adavnce.
Thomas

@edwinhuish
Copy link

@Th0masAAnderson You could change the image directory as below.

image

@rufdev
Copy link

rufdev commented Jul 29, 2020

this was the best guide so far for windows 10. i never got to install portainer using wsl2. the end point is lost after restarting docker but with this guide it worked perfectly.

@paeblits
Copy link

paeblits commented Sep 17, 2020

Didn't see a docker-compose solution so I'm pasting here. You simply need to add a command to your service.

command:
    "-H"
    "tcp://docker.for.win.localhost:2375"`

@oscarsal433
Copy link

Works for me thanks!

@Artekus
Copy link

Artekus commented Mar 15, 2021

tcp://docker.for.win.localhost:2375 has been been removed, it is now tcp://host.docker.internal:2375

docker/for-win#10619 (comment)

@SeanSobey
Copy link
Author

tcp://host.docker.internal:2375

Thanks, updated

@peyrusse
Copy link

It worked for me with tcp://host.docker.internal:2375. Thanks.

@shahidcodes
Copy link

Portainer has official docs on how to use with wsl
https://docs.portainer.io/v/ce-2.9/start/install/server/docker/wsl
no issue so far

@chaoscreater
Copy link

docker: Error response from daemon: invalid volume specification: 'portainer_data:/data'.

@NemchinovSergey
Copy link

Thank you, it worked for me on Windows 10 (build 1809) WSL 1 with tcp://localhost:2375 using a loopback address.

Note: the flag --no-auth is unknown and the container doesn't start with it. I removed it when started the container.

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