{"id":13753244,"url":"https://github.com/jonashackt/ansible-windows-docker-springboot","last_synced_at":"2025-03-19T01:30:56.895Z","repository":{"id":147269186,"uuid":"81327242","full_name":"jonashackt/ansible-windows-docker-springboot","owner":"jonashackt","description":"Example project showing how to provision, deploy, run \u0026 orchestrate Spring Boot apps with Docker Windows Containers on Docker Windows native using Packer, Powershell, Vagrant \u0026 Ansible","archived":false,"fork":false,"pushed_at":"2019-07-22T14:26:48.000Z","size":10315,"stargazers_count":72,"open_issues_count":3,"forks_count":34,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-03-17T01:35:14.196Z","etag":null,"topics":["ansible","chocolatey","devops","docker","docker-compose","docker-container","docker-registry","docker-swarm","packer","powershell","spring-boot","spring-cloud-netflix","vagrant","windows-docker"],"latest_commit_sha":null,"homepage":"https://blog.codecentric.de/en/2017/05/ansible-docker-windows-containers-scaling-spring-cloud-netflix-docker-compose/","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jonashackt.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-02-08T12:21:55.000Z","updated_at":"2025-03-16T02:44:15.000Z","dependencies_parsed_at":null,"dependency_job_id":"61ba6a9f-bbba-4020-addc-7d10a52778f4","html_url":"https://github.com/jonashackt/ansible-windows-docker-springboot","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonashackt%2Fansible-windows-docker-springboot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonashackt%2Fansible-windows-docker-springboot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonashackt%2Fansible-windows-docker-springboot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonashackt%2Fansible-windows-docker-springboot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jonashackt","download_url":"https://codeload.github.com/jonashackt/ansible-windows-docker-springboot/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244336135,"owners_count":20436773,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ansible","chocolatey","devops","docker","docker-compose","docker-container","docker-registry","docker-swarm","packer","powershell","spring-boot","spring-cloud-netflix","vagrant","windows-docker"],"created_at":"2024-08-03T09:01:18.934Z","updated_at":"2025-03-19T01:30:55.637Z","avatar_url":"https://github.com/jonashackt.png","language":"Ruby","readme":"ansible-windows-docker-springboot\n======================================================================================\n[![Build Status](https://travis-ci.org/jonashackt/ansible-windows-docker-springboot.svg?branch=master)](https://travis-ci.org/jonashackt/ansible-windows-docker-springboot)\n[![Ansible Galaxy](https://img.shields.io/badge/galaxy-jonashackt-660198.svg)](https://galaxy.ansible.com/jonashackt)\n\n## Example project showing how to provision, deploy and run Spring Boot apps inside Docker Windows Containers on Windows Host using Packer, Powershell, Vagrant \u0026 Ansible\n\nThis is a follow-up to the repository [ansible-windows-springboot](https://github.com/jonashackt/ansible-windows-springboot) and the blog post [Running Spring Boot Apps on Windows with Ansible (codecentric.de)](https://blog.codecentric.de/en/2017/01/ansible-windows-spring-boot/). There are some corresponding follow up blog posts available:\n\n* [Docker-Windows-Container mit Ansible managen (1/2)](https://www.heise.de/developer/artikel/Docker-Windows-Container-mit-Ansible-managen-1-2-3824736.html) on [heise developer](https://www.heise.de/developer/) (german only)\n* [Running Spring Boot Apps on Docker Windows Containers with Ansible: A Complete Guide incl Packer, Vagrant \u0026 Powershell](https://blog.codecentric.de/en/2017/04/ansible-docker-windows-containers-spring-boot/)\n* [Scaling Spring Boot Apps on Docker Windows Containers with Ansible: A Complete Guide incl Spring Cloud Netflix and Docker Compose](https://blog.codecentric.de/en/2017/05/ansible-docker-windows-containers-scaling-spring-cloud-netflix-docker-compose/)\n\nThis repository uses the following example Spring Boot / Cloud applications for provisioning: [cxf-spring-cloud-netflix-docker](https://github.com/jonashackt/cxf-spring-cloud-netflix-docker)\n\n\n##### Table of Contents  \n[Before you start...](#before-you-start)  \n\n[Preperation: Find a Windows Box - the Evalutation ISO](#preperation-find-a-windows-box---the-evalutation-iso)\n\n[Step 0 - How to build Ansible-ready Vagrant box from a Windows ISO](#step-0---how-to-build-ansible-ready-vagrant-box-from-a-windows-iso-step0-packer-windows-vagrantbox)\n\n[Step 1 - Prepare your Windows Box to run Docker Windows Containers with Ansible](#step-1---prepare-your-windows-box-to-run-docker-windows-containers-with-ansible-step1-prepare-docker-windows)\n\n[Step 2 - How to run a simple Spring Boot App inside a Docker Windows Container with Ansible](#step-2---how-to-run-a-simple-spring-boot-app-inside-a-docker-windows-container-with-ansible-step2-single-spring-boot-app)\n\n[Step 3 - How to scale multiple Spring Boot Apps inside a Docker Windows Containers with Ansible, docker-compose and Spring Cloud Netflix](#step-3---how-to-scale-multiple-spring-boot-apps-inside-a-docker-windows-containers-with-ansible-docker-compose-and-spring-cloud-netflix-step4-multiple-spring-boot-apps-docker-compose)\n\n[Docker Container Orchestration with Linux \u0026 Windows mixed OS setup](#docker-container-orchestration-with-linux--windows-mixed-os-setup)\n\n[Step 4 - A Multi-machine Windows- \u0026 Linux- mixed OS Vagrant setup for Docker Swarm](#step-4---a-multi-machine-windows---linux--mixed-os-vagrant-setup-for-docker-swarm-step4-windows-linux-multimachine-vagrant-docker-swarm-setup)\n\n[Step 5 - Deploy multiple Spring Boot Apps on mixed-OS Docker Windows- \u0026 Linux Swarm with Ansible](#step-5---deploy-multiple-spring-boot-apps-on-mixed-os-docker-windows---linux-swarm-with-ansible-step5-deploy-multiple-spring-boot-apps-to-mixed-os-docker-swarm)\n\n\n\n## Before you start...\n\nBecause [Microsoft \u0026amp; Docker Inc. developed a native Docker implementation on Windows](https://blog.docker.com/2016/09/dockerforws2016/) using Hyper-V (or even a thinner layer) which let´s you run tiny little Windows containers inside your Windows box, which are accessible through the Docker API, I wanted to get my hands on them as soon as I heard of it. A list of [example Windows Docker Images is provided here](https://hub.docker.com/r/microsoft/).\n\nFiring up Spring Boot apps with Ansible on Windows using Docker sound´s like the next step after [Running Spring Boot Apps on Windows with Ansible (codecentric.de)](https://blog.codecentric.de/en/2017/01/ansible-windows-spring-boot/).\n\n\u003e Before we start: The most important point here is to start with a __correct Build Number__ of Windows 10 (1607, Anniversary Update)/Windows Server 2016. It took me days to figure that out, but it won´t work with for example 10.0.14393.67 - but will with 10.0.14393.206! I ran over [the advice on this howto](https://docs.microsoft.com/en-us/virtualization/windowscontainers/quick-start/quick-start-windows-10) to fast, because I thought \"Windows 10 Anniversary should be enough, don´t bother me with build numbers\". But take care! The final `docker run` won´t work (but all the other steps before, which made it so hard to understand)... Here are two examples of the output of a `(Get-ItemProperty -Path c:\\windows\\system32\\hal.dll).VersionInfo.FileVersion` on a Powershell:\n\n__Good build number:__\n\n![Windows_build_number_Docker_working](screenshots/Windows_build_number_Docker_working.png)\n\n__Bad build number:__\n\n![Windows_build_number_Docker_failing](screenshots/Windows_build_number_Docker_failing.png)\n\nBecause of the minimal required build of Windows 10 or Server 2016, we sadly can´t use the easy to download and easy to handle [Vagrant box with Windows 10 from the Microsoft Edge developer site](https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/#downloads). So we have to look after an alternative box to start from. My goal was to start from a original Microsoft Image and show a 100% replicable way how to get to a running Vagrant box. Because besides the Microsoft Edge boxes (which have don´t have the correct build number for now) there aren´t any official from Microsoft around in [Vagrant Atlas](https://atlas.hashicorp.com/boxes/search?utf8=%E2%9C%93\u0026sort=\u0026provider=\u0026q=windows+10). And hey - we´re dealing with Windows! I don´t want to have someone installing things on a VM I don´t know... \n\n\n## Preperation: Find a Windows Box - the Evalutation ISO\n\nAfter a bit of research, you´ll find another way to evaluate a current Windows Version: The [Windows 10 Enterprise Evalutation ISO](https://www.microsoft.com/de-de/evalcenter/evaluate-windows-10-enterprise) or the [Windows Server 2016 Evalutation ISO](https://www.microsoft.com/de-de/evalcenter/evaluate-windows-server-2016). Both the Windows 2016 Server and the 10 Enterprise come with a 180 Days Evaluation licence (you have to register a live-ID for that).\n\n\u003e __DISCLAIMER:__ There are [two Windows Container Types](https://docs.microsoft.com/en-us/virtualization/windowscontainers/about/) : __Windows Server Containers__ (aka isolation level \"process\" or shared Windows kernel) and __Hyper-V-Containers__ (aka isolation level \"hyper-v\"). Windows 10 only supports the latter one. But Hyper-V-Containers seem not the thing you´re used to, when it comes to the Docker core concepts - because Docker relies on Process-Level isolation and __does not__ use a Hypervisor. So with that knowledge I would strongly encourage you to go with Windows Server 2016 and leave Windows 10 behind. At first glance it seems somehow \"easier\" to start with the \"smaller\" Windows 10. But don´t do that! I can also back this advice with lot´s of ours (when not days) trying to get things to work for myself or with customers - and finally switching to Windows Server and everything was just fine!\n\nSo if you really want to go with Windows 10 anyway, it shouldn´t be that much work to write your own Packer template and use the other ISO instead. Here we´ll stay with Windows Server 2016.\n\n\n## Step 0 - How to build Ansible-ready Vagrant box from a Windows ISO ([step0-packer-windows-vagrantbox](https://github.com/jonashackt/ansible-windows-docker-springboot/tree/master/step0-packer-windows-vagrantbox))\n\nThe problem with an ISO - it´s not a nice Vagrant box we can fireup easily for development. But hey! There´s something for us: [packer.io](https://packer.io/). This smart tool is able to produce machine images in every flavour - also as a Vagrant box ;) And [from the docs](https://www.packer.io/docs/post-processors/vagrant.html): \"[Packer] ... is in fact how the official boxes distributed by Vagrant are created.\" On a Mac you can install it with:\n\n`brew install packer` \n\nWe also install Windows completely [unattended](https://social.technet.microsoft.com/wiki/contents/articles/36609.windows-server-2016-unattended-installation.aspx) - which means, we don´t have to click on a single installation screen ;) And we configure it already completely for compatibility with Ansible. Which means several things:\n\n* configure WinRM (aka Powershell remoting) correctly (including Firewall settings)\n* install VirtualBox Guest tools (just for better usability)\n* configure Ansible connectivity \n\nThe WinRM connectivity is configured through the [Autounattend.xml[(https://github.com/jonashackt/ansible-windows-docker-springboot/blob/master/packer/Autounattend.xml). At the end we run the configure-ansible.ps1 - which will call the https://github.com/ansible/ansible/blob/devel/examples/scripts/ConfigureRemotingForAnsible.ps1. But this is done mostly for habing a better feeling, because WinRM should be configured already sufficiently. \n\nIf you like to dig deeper into the myriads of configuration options, have a look into Stefan Scherers GitHub repositories, e.g. https://github.com/StefanScherer/docker-windows-box - where I learned everything I had to - and also borrowed the mentioned [Autounattend.xml[(https://github.com/jonashackt/ansible-windows-docker-springboot/blob/master/packer/Autounattend.xml) from. You can also create one yourself from ground up - but you´ll need a running Windows instance and then install the [Windows Assessment and Deployment Kit (Windows ADK)](https://developer.microsoft.com/de-de/windows/hardware/windows-assessment-deployment-kit).\n\n\n#### Build your Windows Server 2016 Vagrant box\n\nDownload the [Windows_Server_2016_Datacenter_EVAL_en-us_14393_refresh.ISO](https://www.microsoft.com/de-de/evalcenter/evaluate-windows-server-2016) and place it into the __/packer__ folder.\n\nInside the `step0-packer-windows-vagrantbox` directory start the build with this command:\n\n```\npacker build -var iso_url=Windows_Server_2016_Datacenter_EVAL_en-us_14393_refresh.ISO -var iso_checksum=70721288bbcdfe3239d8f8c0fae55f1f windows_server_2016_docker.json\n```\n\nNow get yourself a coffee. This will take some time ;)\n\n#### Add the box and run it\n\n\nAfter successful packer build, you can init the Vagrant box (and receive a Vagrantfile):\n```\nvagrant init windows_2016_docker_virtualbox.box \n```\n\nNow fire up your Windows Server 2016 box:\n\n```\nvagrant up\n```\n\n\n## Step 1 - Prepare your Windows Box to run Docker Windows Containers with Ansible ([step1-prepare-docker-windows](https://github.com/jonashackt/ansible-windows-docker-springboot/tree/master/step1-prepare-docker-windows))\n\nIf you don´t want to go with the discribed way of using packer to build your own Vagrant box and start with your own custom Windows Server 2016 machine right away - no problem! Just be sure to [prepare your machine correctly for Ansible](https://github.com/jonashackt/ansible-windows-springboot#prepare-the-windows-box-for-ansible-communication).\n\nNow let´s check the Ansible connectivity. `cd..` into the root folder `ansible-windows-docker-springboot`:\n\n```\nansible ansible-windows-docker-springboot-dev -i hostsfile -m win_ping\n```\n\nGetting a __SUCCESS__ responde, we can start to prepare our Windows box to run Windows Docker Containers. Let´s run the preparation playbook: \n\n```\nansible-playbook -i hostsfile prepare-docker-windows.yml --extra-vars \"host=ansible-windows-docker-springboot-dev\"\n```\n\nThis does those things for you: \n\n* Checking, if you have the correct minimum build version of Windows\n* Install the necessary Windows Features `containers` and `Hyper-V` (this is done Windows Version agnostic - so it will work with Windows 10 AND Server 2016 - which is quite unique, becaue Microsoft itself always distinquishes between these versions)\n* Reboot your Windows Box, if necessary\n* Install the current Docker version (via [chocolatey docker package](https://chocolatey.org/packages/docker). And although the package claims to only install the client, it also provides the Docker Server (which means this is 100% identical with the [step 2. Install Docker in Microsoft´s tutorial](https://docs.microsoft.com/en-us/virtualization/windowscontainers/quick-start/quick-start-windows-10)).)\n* Register and Start the Docker Windows service\n* Installing docker-compose (this is only needed for multiple containers)\n* Running a first Windows container inside your Windows box (via `docker run microsoft/dotnet-samples:dotnetapp-nanoserver`)\n* Building the `springboot-oraclejre-nanoserver` Docker image to run our Spring Boot Apps later on\n\n\nIf Docker on Windows with Windows Docker Containers is fully configured, you should see something like this (which definitely means, Docker is running perfectly fine on your Windows box!):\n\n```\nTASK [Docker is ready on your Box and waiting for your Containers :)] **********\nok: [127.0.0.1] =\u003e {\n    \"msg\": [\n        \"\", \n        \"        Dotnet-bot: Welcome to using .NET Core!\", \n        \"    __________________\", \n        \"                      \\\\\", \n        \"                       \\\\\", \n        \"                          ....\", \n        \"                          ....'\", \n        \"                           ....\", \n        \"                        ..........\", \n        \"                    .............'..'..\", \n        \"                 ................'..'.....\", \n        \"               .......'..........'..'..'....\", \n        \"              ........'..........'..'..'.....\", \n        \"             .'....'..'..........'..'.......'.\", \n        \"             .'..................'...   ......\", \n        \"             .  ......'.........         .....\", \n        \"             .                           ......\", \n        \"            ..    .            ..        ......\", \n        \"           ....       .                 .......\", \n        \"           ......  .......          ............\", \n        \"            ................  ......................\", \n        \"            ........................'................\", \n        \"           ......................'..'......    .......\", \n        \"        .........................'..'.....       .......\", \n        \"     ........    ..'.............'..'....      ..........\", \n        \"   ..'..'...      ...............'.......      ..........\", \n        \"  ...'......     ...... ..........  ......         .......\", \n        \" ...........   .......              ........        ......\", \n        \".......        '...'.'.              '.'.'.'         ....\", \n        \".......       .....'..               ..'.....\", \n        \"   ..       ..........               ..'........\", \n        \"          ............               ..............\", \n        \"         .............               '..............\", \n        \"        ...........'..              .'.'............\", \n        \"       ...............              .'.'.............\", \n        \"      .............'..               ..'..'...........\", \n        \"      ...............                 .'..............\", \n        \"       .........                        ..............\", \n        \"        .....\", \n        \"\", \n        \"\", \n        \"**Environment**\", \n        \"Platform: .NET Core 1.0\", \n        \"OS: Microsoft Windows 10.0.14393 \", \n        \"\"\n    ]\n}\n\n```\n\n\n## Step 2 - How to run a simple Spring Boot App inside a Docker Windows Container with Ansible ([step2-single-spring-boot-app](https://github.com/jonashackt/ansible-windows-docker-springboot/tree/master/step2-single-spring-boot-app))\n\n\nEverything needed here is inside [step2-single-spring-boot-app](https://github.com/jonashackt/ansible-windows-docker-springboot/tree/master/step2-single-spring-boot-app). Be sure to have cloned and (Maven-) build the example simple Spring Boot app [weatherbackend](https://github.com/jonashackt/spring-cloud-netflix-docker/tree/master/weatherbackend). Let´s cd into `step2-single-spring-boot-app` and run the playbook:\n\n```\nansible-playbook -i hostsfile ansible-windows-docker-springboot.yml --extra-vars \"host=ansible-windows-docker-springboot-dev app_name=weatherbackend jar_input_path=../../cxf-spring-cloud-netflix-docker/weatherbackend/target/weatherbackend-0.0.1-SNAPSHOT.jar\"\n```\n\nThis should run a single Spring Boot app inside a Docker Windows Container on your Windows box.\n\n![spring-boot-example-running-docker-windows-containers](screenshots/spring-boot-example-running-docker-windows-containers.png)\n\n## Step 3 - How to scale multiple Spring Boot Apps inside a Docker Windows Containers with Ansible, docker-compose and Spring Cloud Netflix ([step4-multiple-spring-boot-apps-docker-compose](https://github.com/jonashackt/ansible-windows-docker-springboot/tree/master/step4-multiple-spring-boot-apps-docker-compose))\n\n\nEverything needed here is inside [step3-multiple-spring-boot-apps-docker-compose](https://github.com/jonashackt/ansible-windows-docker-springboot/tree/master/step3-multiple-spring-boot-apps-docker-compose). Be sure to have cloned and (Maven-) build the complete Spring Cloud example apps [cxf-spring-cloud-netflix-docker](https://github.com/jonashackt/spring-cloud-netflix-docker).  Let´s cd into `step3-multiple-spring-boot-apps-docker-compose` and run the playbook:\n\n```\nansible-playbook -i hostsfile ansible-windows-docker-springboot.yml --extra-vars \"host=ansible-windows-docker-springboot-dev\"\n```\n\nThis will fire up multiple containers running Spring Boot Apps inside Docker Windows Containers on your Windows box. They will leverage the power of Spring Cloud Netflix with Zuul as a Proxy and Eureka as Service Registry (which dynamically tells Zuul, which Apps to route).\n\nBut with [docker-compose](https://docs.docker.com/compose/) you are now able to __easily fire up your hole application with one command__ (`docker-compose`) and deployment with Ansible also gets much faster through that (all the Docker containers are build at once and startet in parallel).\nAdditionally, it is now possible to easily scale your Containers. If you want to scale the weatherbackend from 1 to 5 containers for example, just do the following inside __c:\\spring-boot\\__ :\n\n```\ndocker-compose scale weatherbackend=5\n```\n\nA few seconds later (depending on the power of your machine), you should be able to see them all in Eureka:\n\n![spring-cloud-example-running-docker-windows-containers-docker-compose](screenshots/spring-cloud-example-running-docker-windows-containers-docker-compose.png)\n\n\n\n## Best practices\n\n##### Using Powershell on Host to Connect to Container\n\n```\ndocker ps -a \n```\nLook up your containers´ id, then do\n```\ndocker exec -ti YourContainerIdHere powershell\n```\n\n##### Check if your Spring Boot app is running inside the Container\n\n```\niwr http://localhost:8080/swagger-ui.html -UseBasicParsing\n```\n\n##### Set Proxy with Ansible, if you have a corporate firewall\n\nSee https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-docker/configure-docker-daemon:\n\n```\n  - name: Set Proxy for docker pull to work (http)\n    win_environment:\n      state: present\n      name: HTTP_PROXY\n      value: http://username:password@proxy:port/\n      level: machine\n\n  - name: Set Proxy for docker pull to work (https)\n    win_environment:\n      state: present\n      name: HTTPS_PROXY\n      value: http://username:password@proxy:port/\n      level: machine\n```\n\n## Known Issues\n\nIf something doesnt work as expected, see this guide here https://docs.microsoft.com/en-us/virtualization/windowscontainers/troubleshooting\n\nEspecially this command here is useful to check, whether something isn´t working as expected:\n```\nInvoke-WebRequest https://aka.ms/Debug-ContainerHost.ps1 -UseBasicParsing | Invoke-Expression\n```\n\nAnd network seems to be a really tricky part with all this non-localhost, Hyper-V network-stuff ...\n\n#### Network\n\nGood overview:\n\n![windows-docker-network-architecture](screenshots/windows-docker-network-architecture.png)\n(from https://blogs.technet.microsoft.com/virtualization/2016/05/05/windows-container-networking/)\n\n###### Useful commands\n\nShow Docker Networks\n```\ndocker network ls\n```\n\nInspect one of these networks\n```\ndocker network inspect networkNameHere\n```\n\nA good (e.g. working) starting configuration for the Windows Docker Network shows something like this\n\n![docker-network-correct-nat-config](screenshots/docker-network-correct-nat-config.png)\n\nIf the \"IPAM\" section shows an empty Subnet \u0026 Gateway, you may have the problem, that your NAT wont work and you can´t connect to your Docker-Containers from the Windows Docker Host itself (see Caveats and Gotchas section on https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/container-networking)\n\n###### localhost to forward to Windows Containers isn´t working as expected\n\n[On Windows it isn´t possible to do what you know from Linux](https://blog.sixeyed.com/published-ports-on-windows-containers-dont-do-loopback/): Run a `docker run -d -p 80:80 microsoft/iis` and go to `http://localhost` won´t work sadly! But before I hear you scream: \"Hey, why is that `-p 80:80` thingy for - if that simple thing isn´t working?!\" Well, if you come from outside the Windows Docker Host Maschine and try this IP, it will work - so everything will work, except of your localhost-Tests :D\n\n\u003e But this is only temporarily --\u003e The Windows Docker team is on it and the fix will be released soon as a Windows Update - see [github Issue 458](https://github.com/docker/for-win/issues/458)\n\n###### Network docs\n\nHelpful knowledge! Docker Windows Networks work slightly different to Linux ones (localhost!) https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/container-networking\n\nhttps://blogs.technet.microsoft.com/virtualization/2016/05/05/windows-container-networking/\n\nhttps://4sysops.com/archives/windows-container-networking-part-1-configuring-nat/\n\n## Resources\n\n##### Microsoft \u0026 Docker Inc docs\n\n[Windows Containers Documentation](https://docs.microsoft.com/en-us/virtualization/windowscontainers/index)\n\n[Configure Docker on Windows](https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-docker/configure-docker-daemon)\n\nhttps://docs.microsoft.com/en-us/virtualization/windowscontainers/quick-start/quick-start-windows-server\n\nhttps://docs.docker.com/docker-for-windows/troubleshoot/\n\nhttps://docs.docker.com/docker-for-windows/#docker-settings\n\nhttps://www.docker.com/microsoft\n\nhttps://docs.com/taylorb/8408/dockercon-2016-dockerizing-windows-server?c=4TNCe4\n\nhttps://blogs.technet.microsoft.com/virtualization/2016/10/18/use-docker-compose-and-service-discovery-on-windows-to-scale-out-your-multi-service-container-application/\n\nhttps://github.com/Microsoft/Virtualization-Documentation/tree/live/windows-container-samples\n\nhttps://blogs.technet.microsoft.com/virtualization/2017/02/09/overlay-network-driver-with-support-for-docker-swarm-mode-now-available-to-windows-insiders-on-windows-10/\n\nNewest Insider builds: https://insider.windows.com/ or here https://www.microsoft.com/en-us/software-download/windowsinsiderpreviewadvanced\n\n\n##### Good resources\n\nhttps://docs.ansible.com/ansible/devel/plugins/connection.html\n\nhttps://blog.docker.com/2016/09/build-your-first-docker-windows-server-container/\n\n[Walktrough Windows Docker Containers](https://github.com/artisticcheese/artisticcheesecontainer/wiki)\n\n[Video: John Starks’ black belt session about Windows Server \u0026 Docker at DockerCon ‘16](https://www.youtube.com/watch?v=85nCF5S8Qok)\n\nhttps://blog.sixeyed.com/windows-containers-and-docker-5-things-you-need-to-know/\n\nhttps://github.com/StefanScherer/dockerfiles-windows\n\nhttps://github.com/joefitzgerald/packer-windows\n\nhttps://github.com/StefanScherer/docker-windows-box\n\nInstall docker-compose on Windows Server 2016: https://github.com/docker/for-win/issues/448#issuecomment-276328342\n\nIf Service discovery doen´t work reliable: http://stackoverflow.com/questions/43041297/docker-dns-for-service-discovery-to-resolve-windows-container%C2%B4s-address-by-name/43041298#43041298\n\n\n\n# Docker Container Orchestration with Linux \u0026 Windows mixed OS setup\n\nExample steps showing how to provision and run Spring Boot Apps with Docker Swarm \u0026amp; Docker in mixed mode on Linux AND Windows (Docker Windows Containers!)\n\nThis is a follow-up to the blog post [Scaling Spring Boot Apps on Docker Windows Containers with Ansible: A Complete Guide incl Spring Cloud Netflix and Docker Compose](https://blog.codecentric.de/en/2017/05/ansible-docker-windows-containers-scaling-spring-cloud-netflix-docker-compose/)). There are some corresponding follow up blog posts available:\n\n* [Taming the Hybrid Swarm: Initializing a Mixed OS Docker Swarm Cluster Running Windows \u0026 Linux Native Containers with Vagrant \u0026 Ansible](https://blog.codecentric.de/en/2017/09/taming-hybrid-swarm-init-mixed-os-docker-swarm-vagrant-ansible/)\n\n\n## Why more?\n\nWe went quite fare with that setup - and broke up most boundaries inside our heads, what´s possible with Windows. But there´s one step left: leaving the one machine our services are running on and do a step further to go for a multi-machine setup, incl. blue-green-deployments/no-time-out-deployments and kind of \"bring-my-hole-app-UP\" (regardles, on which server it is running)\n\n## Kubernetes or Docker Swarm?\n\nEverything seems to point to Kubernetes - biggest mediashare, most google searches, most blog posts and so on. But there´s one thing that __today__ bring´s me on the Docker Swarm path: And that´s the __Docker Windows Container Support__ in the current feature set implemented. As of Kubernetes 1.6 Windows Server 2016 (which is capable of running Windows Server Containers) there´s a basic support of Docker Windows Containers in Kubernetes - with two main limitations:\n\n* Networksubsystem HNS isn´t really Kubernetes-ready - so you have to manually put Routingtables together\n* Only one Docker Container per Pod is supported right now\n\nBoth things mean, that you litterally can´t leverage the benefits of Kubernetes as a Container Orchestration tool with Docker Windows Containers right now. Things might change soon though, if Microsoft releases it´s Version 1709 Windows Server 2016 and Kubernetes 1.8 goes live. But both isn´t now, so we first of all have to go with the competitor Docker Swarm, which should be also a good thing to start - and we´ll later switch to Kubernetes.\n\n\n## Step 4 - A Multi-machine Windows- \u0026 Linux- mixed OS Vagrant setup for Docker Swarm ([step4-windows-linux-multimachine-vagrant-docker-swarm-setup](https://github.com/jonashackt/ansible-windows-docker-springboot/tree/master/step4-windows-linux-multimachine-vagrant-docker-swarm-setup))\n\nThere are basically two options to achieve a completely comprehensible setup: running more than one virtual machine on your local machine or go into the cloud. To decide which way to go, I had to rethink about what I wanted to show with this project. My goal is to show a setup of an Docker Orchestration tool to scale Docker Containers on both Windows and Linux - without messing with the specialities of one of the many cloud providers. Not to mention the financial perspective. So for the first setup, I wanted to go with a few virtual machines that run on my laptop.\n\nAs I really got to love Vagrant as a tool to handle my Virtual machines, why not do it with that again? And thank´s to a colleague of mine´s hint, I found the [Vagrant multi-machine docs](https://www.vagrantup.com/docs/multi-machine/).\n\n\nInside the `step0-packer-windows-vagrantbox` directory start the build for another Windows box (that does not provide a provider config, which wouldn´t work within a Vagrant multimachine setup) with this command:\n\n```\npacker build -var iso_url=14393.0.161119-1705.RS1_REFRESH_SERVER_EVAL_X64FRE_EN-US.ISO -var iso_checksum=70721288bbcdfe3239d8f8c0fae55f1f -var template_url=vagrantfile-windows_2016-multimachine.template -var box_output_prefix=windows_2016_docker_multimachine windows_server_2016_docker.json\n```\n\nAdd new Windows 2016 Vagrant box:\n```\nvagrant box add --name windows_2016_multimachine windows_2016_docker_multimachine_virtualbox.box\n```\n\nNow switch over to `step4-windows-linux-multimachine-vagrant` directory. Here´s the Vagrantfile defining our local Cloud infrastructure. It defines 4 machines to show the many possible solutions in a hybrid Docker Swarm containing Windows and Linux boxes: Manager nodes both as Windows and Linux machines and Worker nodes, also both as Windows and Linux machines:\n\n* masterlinux01\n* workerlinux01\n* masterwindows01\n* workerwindows01\n\n\nPICTURE!\n\nWithin a Vagrant multimachine setup, you define your separate machines with the `config.vm.define` keyword. Inside those define blocks we simply configure our individual machine. Let´s have a look onto the `workerlinux`:\n\n```\n    # One Worker Node with Linux\n    config.vm.define \"workerlinux\" do |workerlinux|\n        workerlinux.vm.box = \"ubuntu/trusty64\"\n        workerlinux.vm.hostname = \"workerlinux01\"\n        workerlinux.ssh.insert_key = false\n        # Forwarding the port for Ansible explicitely to not run into Vagrants 'Port Collisions and Correction'\n        # see https://www.vagrantup.com/docs/networking/forwarded_ports.html, which would lead to problems with Ansible later\n        workerlinux.vm.network \"forwarded_port\", guest: 22, host: 2232, host_ip: \"127.0.0.1\", id: \"ssh\"\n\n        # As to https://www.vagrantup.com/docs/multi-machine/ \u0026 https://www.vagrantup.com/docs/networking/private_network.html\n        # we need to configure a private network, so that our machines are able to talk to one another\n        workerlinux.vm.network \"private_network\", ip: \"172.16.2.11\"\n\n        workerlinux.vm.provider :virtualbox do |virtualbox|\n            virtualbox.name = \"WorkerLinuxUbuntu\"\n            virtualbox.gui = true\n            virtualbox.memory = 2048\n            virtualbox.cpus = 2\n            virtualbox.customize [\"modifyvm\", :id, \"--ioapic\", \"on\"]\n            virtualbox.customize [\"modifyvm\", :id, \"--vram\", \"16\"]\n        end\n    end\n...\n```\n\nThe first configuration statements are usual ones like configuring the Vagrant box to use or the VM´s hostname. But the fowarded port configuration is made explicit, because we need to rely on the exact port later in our Ansible scripts. And this wouldn´t be possible with Vagrants default [Port Correction feature](https://www.vagrantup.com/docs/networking/forwarded_ports.html). Because you couldn´t use a port on your host machine more then once, Vagrant would automatically set it to a random value - and we weren´t able to access our boxes later with Ansible.\n\nTo define and override the SSH port of a preconfigured Vagrant box, we need to know the `id` which is used to define it in the base box. On Linux boxes this is `ssh` - and on Windows this is `winrm-ssl`.\n\n\n###### Host-only Network configuration\n\nThe next tricky part is the network configuration between the Vagrant boxes. As they need to talk to each other and also to the Host, the so called [Host-only networking](http://www.virtualbox.org/manual/ch06.html#network_hostonly) should be the way to go here (there´s a really good [overview in this post](https://www.thomas-krenn.com/de/wiki/Netzwerkkonfiguration_in_VirtualBox#Host-only_networking), sorry german only). This is easily established using [Vagrants Private Networks configuration](https://www.vagrantup.com/docs/networking/private_network.html).\n\nAnd as we want to access our boxes with a static IP, we leverage the Vagrant configuration around [Vagrant private networking](https://www.vagrantup.com/docs/networking/private_network.html). All that´s needed here, is to have such a line inside every Vagrant box definition of our multi-machine setup:\n\n```\nmasterlinux.vm.network \"private_network\", ip: \"172.16.2.10\"\n```\n\nSame for Windows boxes, Vagrant will tell VirtualBox to create a new separate network (mostly `vboxnet1` or similar), put a second virtual network device into every box and assign with the static IP, we configured in our Vagrantfile. That´s pretty much everything, except for Windows Server :) \n\n\n\n\n\n\n\n#### Network configuration between Vagrant Boxes and the Host\n\nAs Ansible is a really nice tool, that let´s you use the same host in multiple groups - and merges the group_vars from all of those according to that one host - it isn´t a good idea to use a structure like that in your inventory file:\n\n```\n[masterwindows]\n127.0.0.1\n\n[masterlinux]\n127.0.0.1\n\n[workerwindows]\n127.0.0.1\n```\n\nAnd try to use different corresponding group_vars entries... Because, you don´t know, which variables will be present!\n\nSee https://github.com/ansible/ansible/issues/9065\n\n\n###### Different hostnames \n\n\ntbd\n\nBut what if we were able to change the /etc/hosts on our Host machine with every `vagrant up`? (https://stackoverflow.com/questions/16624905/adding-etc-hosts-entry-to-host-machine-on-vagrant-up) That´s possible with the https://github.com/cogitatio/vagrant-hostsupdater, install it with:\n\n```\nvagrant plugin install vagrant-hostmanager\n```\n\n\nCurrent workaround: configure ~/hosts\n\n```\n127.0.0.1 masterlinux01\n127.0.0.1 workerlinux01\n127.0.0.1 masterwindows01\n127.0.0.1 workerwindows01\n```\n\ndo a:\n\n```\nvagrant up\n```\n\nNow we´re ready to play. And nevermind, if you want to have a break or your notebook is running hot - just type a `vagrant halt`. And the whole zoo of machines will be stopped for you :)\n\n\n\n\n\n\n\n\n###### Windows Server firewall blocks Ping \u0026 later needed Container network traffic\n\nAs you may noticed, there´s an extra for Windows Server 2016. Because we want our machines to be accessible from each other, we have to allow the very basic command everybody start´s with: the ping. That one [is blocked by the Windows firewall as a default](https://www.rootusers.com/how-to-enable-ping-in-windows-server-2016-firewall/) and we have to open that up with the following [Powershell command](https://technet.microsoft.com/de-de/library/dd734783(v=ws.10).aspx#BKMK_3_add) - obviously wrapped inside a Ansible task:\n\n```\n  - name: Allow Ping requests on Windows nodes (which is by default disabled in Windows Server 2016)\n    win_shell: \"netsh advfirewall firewall add rule name='ICMP Allow incoming V4 echo request' protocol=icmpv4:8,any dir=in action=allow\"\n    when: inventory_hostname in groups['workerwindows']\n```\n\nAdditionally, and this part is mentioned pretty much at the end of the docker docs if you want to fire up a Swarm, the later established routing network needs access to several ports, [as the docs state](https://docs.docker.com/engine/swarm/ingress/). __AND__ \"you need to have the following ports open between the swarm nodes before you enable swarm mode\". So we need to do that __before__ even initializing our Swarm!\n\n\n\n###### Prepare Docker engines on all Nodes\n\n\u003e __working Ansible SSH config__: you´ll maybe need to install sshpass (e.g. via `brew install https://raw.githubusercontent.com/kadwanev/bigboybrew/master/Library/Formula/sshpass.rb` (as `brew install sshpass` won´t work, see https://stackoverflow.com/questions/32255660/how-to-install-sshpass-on-mac:\n\nBefore (see https://stackoverflow.com/questions/34718079/add-host-to-known-hosts-file-without-prompt/34721229)\n\n```\nexport ANSIBLE_HOST_KEY_CHECKING=False\n```\n\nNow run the following Ansible playbook to prepare your Nodes with a running Docker Engine:\n\n```\nansible-playbook -i hostsfile prepare-docker-nodes.yml\n```\n\n```\nunset ANSIBLE_HOST_KEY_CHECKING\n```\n\n###### Allowing http based local Docker Registries\n\nBut as the [limitations section](https://docs.docker.com/compose/swarm/#limitations) states, we can´t follow our old approach to build our Docker images on the Docker host anymore - because that way we were forced to build those images on all the Swarm´s nodes again and again, which leads to heavy overhead. We should therefore build the Applications Docker image only once and push it into a local Docker registry. But before that, we´ll need such a local registry. This topic is also covered in the [Docker docs](https://docs.docker.com/registry/deploying/#run-the-registry-as-a-service).\n\nThe easiest start here is to use a [plain http registry](https://docs.docker.com/registry/insecure/#deploy-a-plain-http-registry). It´s no problem to run this setup in isolated environments, such as your on-premise servers. Just be sure to update to https with TLS certificates, if you´re going into the cloud or if you want to provide your registry to other users outside this Swarm. \n\nSo let´s go. First of all, we need to allow our Docker Engines on all our hosts to interact with an http-only Docker Registry. Therefore we create a `daemon.json` file with the following entry on all of our nodes:\n\n```\n{\n  \"insecure-registries\" : [\"172.16.2.12:5000\"]\n}\n```\n\nThe file has to reside in `/etc/docker/daemon.json` on Linux and on `C:\\ProgramData\\docker\\config\\daemon.json` on Windows.\n\n\n\n\n\n\n#### Initializing a Docker Swarm\n\n```\nansible-playbook -i hostsfile initialize-docker-swarm.yml\n```\n\nObtaining the worker join-token from the Windows master node isn´t a big problem with Ansible:\n\n```\n  - name: Obtain worker join-token from Windows master node\n    win_shell: \"docker swarm join-token worker -q\"\n    register: token_result\n    ignore_errors: yes\n    when: inventory_hostname in groups['masterwindows']\n```\n\nBut syncing the join-token to the other hosts is a bit tricky, since variables or facts are just defined per Host in Ansible. But there´s help! We only need to use the doc´ info about [Magic Variables, and How To Access Information About Other Hosts](http://docs.ansible.com/ansible/latest/playbooks_variables.html#magic-variables-and-how-to-access-information-about-other-hosts). First of all we access the return variable `token_result` from the Windows master Host `{{ hostvars['masterwindows01']['token_result'] }}` - remember to use the exact Host name here, the group name won´t be enough. The second step is the extraction of the join-token out of the result variable with the help of the set_fact Module. The following two Ansible tasks demonstrate the solution:\n\n```\n  - name: Syncing the worker join-token result to the other hosts\n    set_fact:\n      token_result_host_sync: \"{{ hostvars['masterwindows01']['token_result'] }}\" #\"{{token_result.stdout.splitlines()[0]}}\"\n\n  - name: Extracting and saving worker join-token in variable for joining other nodes later\n    set_fact:\n      worker_jointoken: \"{{token_result_host_sync.stdout_lines}}\"\n\n```\n\n###### Providing a Docker Registry\n\nAs state already in the previous section, we configured every Docker Engine on every Swarm node to enable http only Docker Registry access. Now let´s start our Docker Swarm Registry Service [as mentioned in the docs](https://docs.docker.com/registry/deploying/#run-the-registry-as-a-service). BUT: Currently the docs are wrong - [we´ve got it fixed already here](https://github.com/docker/docker.github.io/pull/4465): \n\n```\n  - name: Specify to run Docker Registry on Linux Manager node\n    shell: \"docker node update --label-add registry=true masterlinux01\"\n    ignore_errors: yes\n    when: inventory_hostname == \"masterlinux01\"\n\n  - name: Create directory for later volume bind-mount into the Docker Registry service on Linux Manager node, if it doesn´t exist\n    file:\n      path: /mnt/registry\n      state: directory\n      mode: 0755\n    when: inventory_hostname == \"masterlinux01\n\n\n  - name: Run Docker Registry on Linux Manager node as Docker Swarm service\n    shell: \"docker service create --name swarm-registry --label registry=true --mount type=bind,src=/mnt/registry,dst=/var/lib/registry -e REGISTRY_HTTP_ADDR=0.0.0.0:5000 -p 5000:5000 --replicas 1 registry:2\"\n    ignore_errors: yes\n    when: inventory_hostname == \"masterlinux01\"\n\n```\n\nAs the [docs do propose a bind-mount](https://docs.docker.com/registry/deploying/#run-the-registry-as-a-service), we have to add `type=bind` into our `--mount` configuration parameter. AND: We have to create the directory `/mnt/registry` beforehand, as the [docs about \"Give a service access to volumes or bind mounts\" are stating](https://docs.docker.com/engine/swarm/services/#give-a-service-access-to-volumes-or-bind-mounts). But it seems, that not all the docs are up-to-date here, see https://github.com/docker/docker.github.io/pull/4641.\n\n\n###### Visualize the Swarm\n\nDocker´s own Swarm visualizer doesn´t look that neat, so I read about a comparison with Portainer: https://stackshare.io/stackups/docker-swarm-visualizer-vs-portainer Seems to be way more prettier! And it say´s in it´s GitHub readme: \"can be deployed as Linux container or a Windows native container\". So let´s integrate it into our setup: \n\nhttps://github.com/portainer/portainer \u0026 https://portainer.readthedocs.io/en/latest/deployment.html\n\nWe therefore integrated Portainer into the initialization process of our Swarm:\n\n```\n- name: Create directory for later volume mount into Portainer service on Linux Manager node, if it doesn´t exist\n  file:\n    path: /mnt/portainer\n    state: directory\n    mode: 0755\n  when: inventory_hostname in groups['linux']\n\n- name: Run Portainer Docker and Docker Swarm Visualizer on Linux Manager node as Swarm service\n  shell: \"docker service create --name portainer --publish 9000:9000 --constraint 'node.role == manager' --constraint 'node.labels.os==linux' --mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock --mount type=bind,src=/mnt/portainer,dst=/data portainer/portainer -H unix:///var/run/docker.sock\"\n  ignore_errors: yes\n  when: inventory_hostname == \"masterlinux01\"\n```\n\nThis will deploy a Portainer instance onto our Linux Manager nodes (masterlinux01, cause we only have one Linux Manager node) and connect it directly to the Swarm.\n\nBut there´s one thing, that could lead to frustration: Use a current Browser to access Portainer UI inside your Windows Boxes! It doesn´t work inside the pre-installed IE! Just head to http://172.16.2.10:9000.\n\n![first-docker-swarm-services-running-portainer](screenshots/first-docker-swarm-services-running-portainer.png)\n\n\n###### Checking swarm status\n\nJust do a `docker info` on one (or all) of the boxes.\n\nNow that we also added Docker labels (like this `docker node update --label-add os=linux masterlinux01`) to each of our nodes so that we can differentiate the OS dependend services later on and also created a Docker Swarm overlay network with `docker network create --driver=overlay mixed_swarm_net`, our Ansible playbook should finally give some output like this:\n\n```\nTASK [Swarm initialized...] *****************************************************************************************************************************\nskipping: [workerwindows01]\nskipping: [masterlinux01]\nok: [masterwindows01] =\u003e {\n    \"msg\": [\n        \"The status of the Swarm now is:\", \n        [\n            \"ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS\", \n            \"ar2mci5utfwov44x42fihgmtf     masterlinux01       Ready               Active              Reachable\", \n            \"qdcarj7mzjl37txmsijgrvxt4     workerwindows01     Ready               Active              \", \n            \"sqirk9itzxlytf5blteg9no7w *   masterwindows01     Ready               Active              Leader\", \n            \"vz8ruili76n8fslo2vo35go3b     workerlinux01       Ready               Active              \"\n        ]\n    ]\n}\nskipping: [workerlinux01]\n```\n\nThis means that our Docker Swarm cluster is ready for service deployment!\n\n\n\n\n\n## Step 5 - Deploy multiple Spring Boot Apps on mixed-OS Docker Windows- \u0026 Linux Swarm with Ansible ([step5-deploy-multiple-spring-boot-apps-to-mixed-os-docker-swarm](https://github.com/jonashackt/ansible-windows-docker-springboot/tree/master/step5-deploy-multiple-spring-boot-apps-to-mixed-os-docker-swarm))\n\nAs Microsoft states in the [Swarm docs](https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/swarm-mode), Docker Swarm Services can be easily deployed to the Swarm with the `docker service create` command and afterwards scaled with `docker service scale`. There´s a huge amount on configuration parameters you can use [with docker service create](https://docs.docker.com/engine/swarm/services/).\n\n__BUT:__ That approach reminds us of those first days with Docker not using Docker Compose. So it would be really nice to have something like Compose also for our Swarm deployment. And it´s really that simple - [just use Compose with Docker Stack Deploy for that :)](https://docs.docker.com/engine/swarm/stack-deploy/):\n\n\u003e \"Docker Compose and Docker Swarm aim to have full integration, meaning you can point a Compose app at a Swarm cluster and have it all just work as if you were using a single Docker host.\"\n\nBack to the concrete docker-compose.yml file. Let´s use the [newest 3.3 version](https://docs.docker.com/compose/compose-file/compose-versioning/#version-33) here, so that we can leverage the most out of Swarm´s functionality, which is broadened with each Compose (file) version.\n\n\n\n#### The Windows Server 2016 Issue\n\nI really like to have completely comprehensible setups! The problem here is, that our setup based on __Windows Server 2016 isn´t going to support access to our deployed applications__ in the end! Why is that? The problem is all about the unsupported routing mesh!\n \nYou may say, hey there´s a workaround: Docker Swarm publish-port mode! As https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/swarm-mode#publish-ports-for-service-endpoints states, there´s an alternative to routing mesh: Docker Swarm´s publish-port mode. With a Docker Stack deploy, this could look like the following in the docker-stack.yml:\n\n```\n    deploy:\n      ...\n      endpoint_mode: dnsrr\n```\n\nBut together with setting the `endpoint_mode` to DNS round-robin (DNSRR) as [described in the docs](https://docs.docker.com/compose/compose-file/#endpoint_mode), we also need to alter the [exported Ports settings](https://docs.docker.com/compose/compose-file/#ports). We need to set it to `mode: host`, which is only possible with [the long syntax](https://docs.docker.com/compose/compose-file/#long-syntax-2) in the Docker Stack / Compose file format:\n\n```\n    ports:\n      - target: {{ service.port }}\n        published: {{ service.port }}\n        protocol: tcp\n        mode: host\n```\n\nOtherwise the Docker engine will tell us the following error: `Error response from daemon: rpc error: code = 3 desc = EndpointSpec: port published with ingress mode can't be used with dnsrr mode`\n\n__BUT!__ the problem with this configuration is, that Traefik won´t support this in the end! It really took me days to find out, that using Windows Server 2016 together with Docker Swarm publish-port mode and `endpoint_mode` isn´t going to work together with a Loadbalancer like Traefik. And we´ll need one! The following paragraphs will show you, why.\n\n\n\n\n#### The Alternative: Windows Server 1709 or 1803 (Semi-annual Channel)\n\nWindows Server 2016 is the LTS version of the Windows Server family, which will be supported with smaller Updates - but no real new bleeding edge stuff. And Docker network routing mesh support is introduced first in Windows Server 1709: \nhttps://blog.docker.com/2017/09/docker-windows-server-1709/\nhttps://blogs.technet.microsoft.com/virtualization/2017/09/26/dockers-ingress-routing-mesh-available-with-windows-server-version-1709/\n\nAlso see my comments there:\n\n\u003e Hi Kallie, to use the new features in production at the customer, we need to have access to the new 1709 build of Windows Server 2016. As this post here https://blogs.technet.microsoft.com/windowsserver/2017/10/17/windows-server-version-1709-available-for-download/ states, the 1709 build will only be available in the so called “Semi-annual channel”, which is only available for customers if they have the “Software Assurance” package (as this post states https://cloudblogs.microsoft.com/hybridcloud/2017/06/15/delivering-continuous-innovation-with-windows-server/).\n\n\u003e To provide a recommendation for the customer, that is based on a proven and fully automated “infrastructure as code” example, I successfully build a GitHub repo (https://github.com/jonashackt/ansible-windows-docker-springboot) with EVERY needed step, beginning with the download of a evaluation copy of Windows Server 2016 from here https://www.microsoft.com/de-de/evalcenter/evaluate-windows-server-2016, going over to a setup with VirtualBox/Vagrant (https://www.vagrantup.com/), Provisioning with Ansible and (https://www.ansible.com/) and finally running and scaling Spring Boot apps Dockerized on the Windows Server.\n\n\u003e Now the next step is Docker orchestration with Swarm (and later Kubernetes). But with the current version of https://www.microsoft.com/de-de/evalcenter/evaluate-windows-server-2016, the mentioned Docker network routing mesh support isn´t available for us. Is there any chance to update this version in the evalcenter? I know there´s the Insiderprogram, but I doesn´t really help my to have a fully trustable setup where I can prove for everybody, that everything will work.\n\n__TLDR:__\n\n--\u003e only available in Windows Server 1709: https://blogs.technet.microsoft.com/windowsserver/2017/10/17/windows-server-version-1709-available-for-download/\n\n--\u003e only available in the \"Semi-annual channel\", which is according to https://cloudblogs.microsoft.com/hybridcloud/2017/06/15/delivering-continuous-innovation-with-windows-server/ only available with the \"Software Assurance\" package you have to buy separately to the Server licence \n\n--\u003e only alternative: Windows Insider program: https://www.microsoft.com/en-us/software-download/windowsinsiderpreviewserver\n\n--\u003e but this isn´t a good start with customers!\n\n\n\n#### Building a Windows Server 1709 or 1803 Vagrant Box with Packer\n\nNow that __we need__ to use Windows Server 1709 or 1803 as a basis, we have to build a new Vagrant Box with Packer. The Packer configuration file [windows_server_2016_docker.json](https://github.com/jonashackt/ansible-windows-docker-springboot/blob/master/step0-packer-windows-vagrantbox/windows_server_2016_docker.json) is flexible enough to support all three Windows Server variants: 2016, 1709 or 1803. \n\nSo let´s build our Windows Server 1803 Vagrant Box. All you need is an ISO like `en_windows_server_version_1803_x64_dvd_12063476.iso` incl. a matching MD5 checksum, which should be available through the \"Software Assurance\" package or a MSDN Subscription (if you have one) - or at least at the [Windows Insider program]( https://www.microsoft.com/en-us/software-download/windowsinsiderpreviewserver). If you have the ISO and MD5 ready, fire up the Packer build:\n\n```\npacker build -var iso_url=en_windows_server_version_1803_x64_dvd_12063476.iso -var iso_checksum=e34b375e0b9438d72e6305f36b125406 -var template_url=vagrantfile-windows_1803-multimachine.template -var box_output_prefix=windows_1803_docker_multimachine windows_server_2016_docker.json\n```\n\nIf that is finished, add the new box to your Vagrant installation:\n\n```\nvagrant box add --name windows_1803_docker_multimachine windows_1803_docker_multimachine_virtualbox.box\n```\n\n##### TODO:\nBe sure to have the latest updates installed! For me, it only worked after the November 2017 culmulative update package, with [KB4048955](https://support.microsoft.com/en-us/help/4048955/windows-10-update-kb4048955) inside. Otherwise ingress networking mode (`deploy: endpoint_mode: vip`) __DOESN´T WORK!__\n\n\n\n#### Switch the base Docker image\n\n\nThere´s another difference to the Standard Windows Server 2016 LTS Docker images: The nanoserver and windowsservercore Images are much smaller! BUT: The nanoserver now misses the Powershell! Well, that´s kind of weird - but it´s kind of like in the Linux world, where you don´t have a bash installed per se, but only sh... But there´s help. Microsoft provides a nanoserver with Powershell on top right on Dockerhub: https://hub.docker.com/r/microsoft/powershell/ To pull the correct nanoserver with Powershell, just use:\n\n```\ndocker pull microsoft/powershell:nanoserver\n```\n\nBut as we use the latest `nanoserver:1709 image, we also have to use the suitable 1709er image for powershell: `microsoft/powershell:6.0.0-rc-nanoserver-1709` - kind of weird again that its only __rc__ right now, but hey. :)\n\nNow you also have to keep in mind, that you have to use `pwsh` instead of `powershell` to enter the Powershell inside a Container:\n\n```\ndocker exec -it ContainerID pwsh\n```\n\n\n\n\n\n#### Main Playbook build-and-deploy-apps-2-swarm.yml structure \n\ncd into [step5-deploy-multiple-spring-boot-apps-to-mixed-os-docker-swarm](https://github.com/jonashackt/ansible-windows-docker-springboot/tree/master/step5-deploy-multiple-spring-boot-apps-to-mixed-os-docker-swarm) and run:\n\n```\nansible-playbook -i hostsfile build-and-deploy-apps-2-swarm.yml\n```\n\nThe playbook has 4 main steps:\n\n```\n  - name: 1. Build Linux Apps Docker images on Linux manager node and push to Docker Swarm registry\n    include_tasks: prepare-docker-images-linux.yml\n    with_items: \"{{ vars.services }}\"\n    when: inventory_hostname == \"masterlinux01\" and item.deploy_target == 'linux'\n    tags: buildapps\n\n  - name: 2. Build Windows Apps Docker images on Windows manager node and push to Docker Swarm registry\n    include_tasks: prepare-docker-images-windows.yml\n    with_items: \"{{ vars.services }}\"\n    when: inventory_hostname == \"masterwindows01\" and item.deploy_target == 'windows'\n    tags: buildapps\n\n  - name: 3. Open all published ports of every app on every node for later access from outside the Swarm\n    include_tasks: prepare-firewall-app-access.yml\n    with_items: \"{{ vars.services }}\"\n    tags: firewall\n\n  - name: 4. Deploy the Stack to the Swarm on Windows Manager node\n    include_tasks: deploy-services-swarm.yml\n    when: inventory_hostname == \"masterwindows01\"\n    tags: deploy\n```\n\n\n#### Build Docker images of all Spring Boot apps and push them to Docker Swarm registry\n\nFirst we need to build all Docker images of all Spring Boot apps (according to which OS they should run on) and push them to Docker Swarm registry. This is done by the [prepare-docker-images-linux.yml](prepare-docker-images-linux.yml) and the [prepare-docker-images-windows.yml](prepare-docker-images-windows.yml). They are pushing the Applications new Docker image into our Swarm registry at the end:\n\n```\n  - name: Push the Docker Container image to the Swarm Registry\n    shell: \"docker push {{registry_host}}/{{spring_boot_app.name}}:latest\"\n```\n\n\n#### Open all Apps´ ports on every host!\n\n\nFrom https://docs.docker.com/engine/swarm/ingress/:\n\n\u003e \"You must also open the published port between the swarm nodes and any external resources, such as an external load balancer, that require access to the port.\"\n\nSo we need to open every port of every application on every host! Therefor we use __prepare-firewall-app-access.yml__, that opens all needed ports in our hybrid swarm:\n\n```\n  - name: Preparing to open...\n    debug:\n      msg: \"'{{ item.name }}' with port '{{ item.port }}'\"\n\n  - name: Open the apps published port on Linux node for later access from outside the Swarm\n    ufw:\n      rule: allow\n      port: \"{{ item.port }}\"\n      proto: tcp\n      comment: \"{{ item.name }}'s port {{ item.port }}\"\n    become: true\n    when: inventory_hostname in groups['linux']\n\n  - name: Open the apps published port on Windows node for later access from outside the Swarm\n    win_firewall_rule:\n      name: \"{{ item.name }}'s port {{ item.port }}\"\n      localport: \"{{ item.port }}\"\n      action: allow\n      direction: in\n      protocol: tcp\n      state: present\n      enabled: yes\n    when: inventory_hostname in groups['windows']\n```\n\n\n\n\n#### Deploy the Stack to the Swarm\n\nFrom https://docs.docker.com/get-started/part5/#introduction:\n\u003e \"A stack is a group of interrelated services that share dependencies, and can be orchestrated and scaled together. A single stack is capable of defining and coordinating the functionality of an entire application.\"\n\nThink of a Stack as like what Compose is for Docker - grouping multiple Docker Swarm services together with the help of a docker-stack.yml (which looks like a docker-compose.yml file and uses nearly the same syntax (Stack has 'deploy' over Compose)). An example `docker-stack.yml` looks like:\n\n```\ntbadded\n```\n\nDon´t try to search for \"Docker Stack command reference\", just head over to the Docker Compose docs and you should find, what you need: https://docs.docker.com/compose/compose-file/#deploy Because Docker Swarm makes use of Docker Compose files, the Swarm capabilities of Stack are only just a section (`deploy`) in the Compose docs.\n\nWe should see our applications in Portainer now:\n\n![portainer-swarm-visualizer](screenshots/portainer-swarm-visualizer.png)\n\n\n\n\n\n#### Accessing Spring Boot applications deployed in the Swarm\n\n\nFore more indepth information how Docker Swarm works, have a look at https://docs.docker.com/engine/swarm/how-swarm-mode-works/services/\n\n![how-swarm-services-work](screenshots/how-swarm-services-work.png)\n\nTo get to know, where your App is accessible in the Swarm, there are some commands you can use. On a manager node do a\n\n```\ndocker service ls\n```\n\nto see all the deployed Docker Swarm services. It should output something like:\n\n![docker-service-ls](screenshots/docker-service-ls.png)\n\nNow pick one of your Services to inspect and do a\n\n```\ndocker service ps clearsky_weatherbackend\n```\n\nThis should show us, on which node the Swarm manager is running the Docker Swarm task including our App´s container:\n\n![docker-service-ps-app](screenshots/docker-service-ps-app.png)\n\nIt´s `workerlinux01` in this example.\n\nIf you´re unsure, which Port is mapped to the Docker node workerlinux01, you could run a:\n\n```\ndocker service inspect --pretty clearsky_weatherbackend\n```\n\nThis should give you more insights into this app, including the mapped Port 30001:\n\n![docker-service-inspect-app](screenshots/docker-service-inspect-app.png)\n\nWith all this information, you could check out your first Docker Swarm deployed App. Just log into `workerlinux01` and call your App, e.g. with a `curl http://localhost:30001/swagger-ui.html` - as the [weatherbackend](https://github.com/jonashackt/cxf-spring-cloud-netflix-docker) is usind [Springfox](https://github.com/springfox/springfox) together with Swagger to show all of it´s REST endpoints:\n\n![curl-linux-container](screenshots/curl-linux-container.png)\n\nAs Windows doesn´t support localhost loopback, we have to add one more step, to access an App which is deployed into a Windows native Docker Container: We need to know the Container´s IP:\n\n\n__BUT:__ We´re not in Docker Engine´s standard mode anymore, we´re in Swarm mode. So the Ports aren´t mapped to the Host we define, but to the Docker Swarm as a hole. How does this work? This is done through Docker Swarm Routing Mesh:\n\n\u003e \"When you publish a service port, the swarm routing mesh makes the service accessible at the target port on every node regardless if there is a task for the service running on the node.\"\n\nhttps://docs.docker.com/engine/swarm/ingress/\n\n![ingress-routing-mesh](screenshots/ingress-routing-mesh.png)\n\n\n##### Test ingress networking \n\n\nTo see, if a Docker Swarm service with ingress networking mode is able to run, fire up a test service:\n\n__TODO__: use a service, that doesn´t need the other following steps\n\n```\ndocker service create --name weathertest --network swarmtest --publish 9099:9099 --endpoint-mode vip 172.16.2.10:5000/weatherbockend\n``` \n\n\n\n\n\n\n\n## DNS to avoid the Host specification of the HTTP-header\n\nLet´s try [vagrant-dns Plugin](https://github.com/BerlinVagrant/vagrant-dns)\n\n```\nvagrant plugin install vagrant-dns\n```\n\nNow configure TLD for `masterlinux01` in the Vagrant multi-machine setup:\n\n```\nmasterlinux.vm.hostname = \"masterlinux01\"\n\nmasterlinux.dns.tld = \"test\"\n```\n\nNow register the vagrant-dns server as a resolver:\n\n```\nvagrant dns --install\n```\n\nNow check with `scutil --dns`, if the resolver is part of your DNS configuration:\n\n```\n...\n\nresolver #9\n  domain   : test\n  nameserver[0] : 127.0.0.1\n  port     : 5300\n  flags    : Request A records, Request AAAA records\n  reach    : 0x00030002 (Reachable,Local Address,Directly Reachable Address)\n\n...\n```\n\nThis looks good! Now try, if you´re able to reach our Vagrant Boxes using our defined domain by typing e.g. `dscacheutil -q host -a name foo.masterwindows01.test`:\n\n```\n$:step4-windows-linux-multimachine-vagrant-docker-swarm-setup jonashecht$ dscacheutil -q host -a name foo.masterwindows01.test\nname: foo.masterwindows01.test\nip_address: 172.16.2.12\n\n$:step4-windows-linux-multimachine-vagrant-docker-swarm-setup jonashecht$ dscacheutil -q host -a name foo.masterlinux01.test\nname: foo.masterlinux01.test\nip_address: 172.16.2.10\n\n$:step4-windows-linux-multimachine-vagrant-docker-swarm-setup jonashecht$ dscacheutil -q host -a name bar.workerlinux01.test\nname: bar.workerlinux01.test\nip_address: 172.16.2.11\n\n$:step4-windows-linux-multimachine-vagrant-docker-swarm-setup jonashecht$ dscacheutil -q host -a name foobar.workerwindows01.test\nname: foobar.workerwindows01.test\nip_address: 172.16.2.13\n```\n\n\nBut as the [vagrant-dns Plugin](https://github.com/BerlinVagrant/vagrant-dns) doesn´t support propagating the host´s DNS resolver to the Vagrant Boxes, we soon are running into problems - because Traefik couldn´t route any request anymore. But luckily we have [VirtualBox as a virtualization provider for Vagrant](https://www.vagrantup.com/docs/virtualbox/common-issues.html), which supports the propagation of the host´s DNS resolver to the guest machines. All we have to do, is to use [this suggestion on serverfault](https://serverfault.com/a/506206/326340):, which will 'Using the host's resolver as a DNS proxy in NAT mode':\n\n```\n# Forward DNS resolver from host (vagrant dns) to box\nvirtualbox.customize [\"modifyvm\", :id, \"--natdnshostresolver1\", \"on\"]\n```\n\nAfter we configured that, we can do our well-known `vagrant up`.\n\n\nNow we should be able to do this:\n\n```\ncurl weatherbockend.masterlinux01.test:80 -v\n```\n\nWe´re using port `80` here, because `masterlinux01.test` directly resolves to `172.16.2.10` - which is the named box :) And as Traefik is waiting for requests on port `80`, this should work.\n\nOr go to your Browser and simply try out all possible urls! Here are a few:\n\n```\nhttp://weatherbockend.masterlinux01.test/swagger-ui.html\nhttp://weatherbockend.masterlinux01.test/weather/general/outlook\nhttp://weatherservice.masterlinux01.test/soap\nhttp://weatherbockend.masterlinux01.test/swagger-ui.html\n```\n\n\n\n## Fixing 'mount -t vboxsf ... No such device' errors because of old VirtualBox additions in VagrantBoxes\n\n```\nvagrant plugin install vagrant-vbguest\n```\n\n\n\n\n\n#### Using Traefik to access Spring Boot Apps\n\n[Docker Stack deploy for Apps provided by Traefik](https://github.com/containous/traefik/issues/994#issuecomment-269095109)\n\nIf you now access http://localhost:48080/, you should see the Traefik dashboard with all the Services deployed:\n\n![first-successful-traefik-service-deployment-incl-registered-apps](screenshots/first-successful-traefik-service-deployment-incl-registered-apps.png)\n\nTherefore the [Vagrantfile](https://github.com/jonashackt/ansible-windows-docker-springboot/blob/master/step4-windows-linux-multimachine-vagrant-docker-swarm-setup/Vagrantfile) has some more port forwardings prepared:\n\n```\n        # Forwarding the Guest to Host ports, so that we can access it easily from outside the VM\n        workerlinux.vm.network \"forwarded_port\", guest: 8080, host: 48081, host_ip: \"127.0.0.1\", id: \"traefik_dashboard\"\n        workerlinux.vm.network \"forwarded_port\", guest: 80, host: 40081, host_ip: \"127.0.0.1\", id: \"traefik\"\n```\n\nThe Apps are templated over the docker-stack.yml:\n\n```\nservices:\n\n{% for service in vars.services %}\n  {{ service.name }}:\n    image: {{registry_host}}/{{ service.name }}\n    ports:\n      - target: {{ service.port }}\n        published: {{ service.port }}\n        protocol: tcp\n    tty:\n      true\n    restart:\n      unless-stopped\n    deploy:\n      endpoint_mode: vip\n      replicas: {{ service.replicas }}\n      placement:\n{% if service.deploy_target == 'windows' %}\n        constraints: [node.labels.os==windows]\n{% else %}\n        constraints: [node.labels.os==linux]\n{% endif %}\n      labels:\n        - \"traefik.port={{ service.port }}\"\n        - \"traefik.docker.network={{ swarm_network_name }}\"\n        - \"traefik.backend={{ service.name }}\"\n# Use Traefik healthcheck        \"traefik.backend.healthcheck.path\": \"/healthcheck\",\n        - \"traefik.frontend.rule=Host:{{ service.name }}.{{ docker_domain }}\"\n\n```\n\nNote that the `traefik.port=YourAppPort` must be the same port, that your Spring Boot application uses (via `server.port=YourAppPort`) and your Container exposes. Then Traefik will automatically route a Request through to the App over the configured first published Port:\n\n```\n   ports:\n      - target: 80\n        published: 80\n        protocol: tcp\n        mode: host\n```\n\nFinally the first curls are working:\n\n```\ncurl -H Host:eureka-serviceregistry.sky.test http://localhost:40080 -v\n```\n\n![first-successful-app-call-through-traefik](screenshots/first-successful-app-call-through-traefik.png)\n\n\n\n\nAs we also added a port forwarding configuration for every app in our [Vagrantfile](https://github.com/jonashackt/ansible-windows-docker-springboot/blob/master/step4-windows-linux-multimachine-vagrant-docker-swarm-setup/Vagrantfile):\n\n```\n        # Open App ports for access from outside the VM\n        masterlinux.vm.network \"forwarded_port\", guest: 8761, host: 8761, host_ip: \"127.0.0.1\", id: \"eureka\"\n        masterlinux.vm.network \"forwarded_port\", guest: 8090, host: 8090, host_ip: \"127.0.0.1\", id: \"weatherbackend\"\n        masterlinux.vm.network \"forwarded_port\", guest: 8091, host: 8091, host_ip: \"127.0.0.1\", id: \"weatherbockend\"\n        masterlinux.vm.network \"forwarded_port\", guest: 8095, host: 8095, host_ip: \"127.0.0.1\", id: \"weatherservice\"\n```\n\n, we should now be able to access every app from our Vagrant/VirtualBox host:\n\n![all-apps-available-via-routing-mesh](screenshots/all-apps-available-via-routing-mesh.png).\n\nNow we should check, if the containers are able to reach themselfes. So for example we could try to reach a Windows Container from within the scope of an Linux Container from `masterlinux01`:\n\n```\ndocker exec -it e71 ping weatherservice\n```\n\nLet´s have a look onto all containers and services in the network. Therefore you __MUST__ use the full network name, the id isn´t giving you the full output of everything in the Cluster! (as https://github.com/moby/moby/pull/31710 states, you need `--verbose` to see all data from all nodes!)\n\n```\ndocker network inspect --verbose clearsky_mixed_swarm_net\n```\n\nhttps://github.com/docker/for-win/issues/1366\n\n--\u003e Let´s try another Baseimage and switch to https://hub.docker.com/r/microsoft/windowsservercore/ with `microsoft/windowsservercore:1709`\n\n\nTest via Traefik:\n\n```\ncurl -H Host:weatherbackend.sky.test http://localhost:40080 -v\n```\n\nAnd __IT WORKS!!!__:\n\n![first-successful-call-to-both-windows-and-linux-containers-through-traefik](screenshots/first-successful-call-to-both-windows-and-linux-containers-through-traefik.png).\n\nAlso all the example apps ([cxf-spring-cloud-netflix-docker](https://github.com/jonashackt/cxf-spring-cloud-netflix-docker)) will call themselfes if you call the weatherservice with SoapUI for example:\n\n![first-full-call-through-traefik-mixed-os-apps-incl-eureka-feign-soapui-client](screenshots/first-full-call-through-traefik-mixed-os-apps-incl-eureka-feign-soapui-client.png)\n\nThe really use Eureka \u0026 Feign to call each other:\n\n![docker-swarm-services-registered-eureka](screenshots/docker-swarm-services-registered-eureka.png)\n\n\n\n\n\n# Links\n\n#### General comparison of Docker Container Orchestrators\n\nmarketshare: https://blog.netsil.com/kubernetes-vs-docker-swarm-vs-dc-os-may-2017-orchestrator-shootout-fdc59c28ec16\n\nhttps://www.loomsystems.com/blog/single-post/2017/06/19/kubernetes-vs-docker-swarm-vs-apache-mesos-container-orchestration-comparison\n\n\n#### Windows Server\n\nhttps://blogs.technet.microsoft.com/hybridcloud/\n\nhttps://blogs.technet.microsoft.com/hybridcloud/2017/05/10/windows-server-for-developers-news-from-microsoft-build-2017/\n\nWindows Server Pre-Release (Insider): https://www.microsoft.com/en-us/software-download/windowsinsiderpreviewserver\n\nCurrent state discription: https://blogs.windows.com/windowsexperience/2017/07/13/announcing-windows-server-insider-preview-build-16237/#tx4mFJzTSMIjl2gX.97 --\u003e coming version 1709 of Windows Server 2016 will have better Kubernetes support with no more manual tinkering with routing tables (better HNS)\n\n--\u003e LinuxKit in Hyper-V for Side-by-Side Windows and Linux deployments: https://dockercon.docker.com/watch/U7Bxp66uKmemZssjCTyXkm\n\nWhat´s new in 1803: https://docs.microsoft.com/en-us/windows-server/get-started/whats-new-in-windows-server-1803\n\n\n#### Docker Swarm\n\nDocker Swarm Windows Docs: https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/swarm-mode\n\nWindows Server 2016 Overlay Networking Support (Windows \u0026 Linux mixed mode): https://blogs.technet.microsoft.com/virtualization/2017/04/18/ws2016-overlay-network-driver/\n\nhttps://blogs.technet.microsoft.com/virtualization/2017/02/09/overlay-network-driver-with-support-for-docker-swarm-mode-now-available-to-windows-insiders-on-windows-10/\n\nWindows \u0026 Linux mixed Video: https://www.youtube.com/watch?v=ZfMV5JmkWCY\n\nhttps://docs.docker.com/engine/swarm/\n\nhttps://docs.docker.com/engine/swarm/key-concepts/\n\nhttps://docs.docker.com/engine/swarm/services/\n\ndocker service create CLI reference: https://docs.docker.com/engine/reference/commandline/service_create/\n\nhttps://docs.docker.com/engine/swarm/stack-deploy/\n\nhttps://codefresh.io/blog/deploy-docker-compose-v3-swarm-mode-cluster/\n\nDocker network routing mesh support in Windows Server 2016 1709: https://blog.docker.com/2017/09/docker-windows-server-1709/ \u0026 https://blogs.technet.microsoft.com/virtualization/2017/09/26/dockers-ingress-routing-mesh-available-with-windows-server-version-1709/\n\nhttps://blogs.technet.microsoft.com/windowsserver/2017/10/17/windows-server-version-1709-available-for-download/\n\nhttps://www.microsoft.com/en-us/software-download/windowsinsiderpreviewserver\n\nAutoscaler for Docker Swarm: https://github.com/gianarb/orbiter\n\n\n\n\n\n\n#### Kubernetes\n\nDocker Windows Containers \u0026 Kubernetes: https://blogs.technet.microsoft.com/networking/2017/04/04/windows-networking-for-kubernetes/\n\nKubernetes Networking on Windows: https://www.youtube.com/watch?v=P-D8x2DndIA\u0026t=6s\u0026list=PL69nYSiGNLP2OH9InCcNkWNu2bl-gmIU4\u0026index=1\n\nhttps://docs.microsoft.com/en-us/virtualization/windowscontainers/kubernetes/getting-started-kubernetes-windows\n\n\nhttp://www.serverwatch.com/server-news/why-kubernetes-sucks-and-how-to-fix-it.html\n\nhttp://blog.kubernetes.io/2016/12/windows-server-support-kubernetes.html\n\nhttps://www.youtube.com/watch?v=Tbrckccvxwg\n\nhttps://kubernetes.io/docs/getting-started-guides/windows/\n\nhttps://github.com/kubernetes/features/issues/116\n\nminikube howto: http://www.sqlservercentral.com/blogs/the-database-avenger/2017/06/13/orchestrating-sql-server-with-kubernetes/\n\nhttps://groups.google.com/forum/#!forum/kubernetes-sig-windows\n\nhttp://blog.kubernetes.io/2017/08/kompose-helps-developers-move-docker.html?m=1\n\nhttp://blog.kubernetes.io/2017/09/windows-networking-at-parity-with-linux.html\n\n\n#### Spring Application Deployment\n\nSpring Cloud kubernetes https://github.com/spring-cloud-incubator/spring-cloud-kubernetes\n\nShutdown hooks https://www.gesellix.net/post/zero-downtime-deployment-with-docker-stack-and-spring-boot/\n\nDeployment example with Spring Cloud http://pscode.rs/spring-cloud-with-spring-config-and-eureka-in-high-availability-using-docker-swarm/\n\nWindows JDK Docker images: https://hub.docker.com/_/openjdk/\n\n\n#### Traefik\n\nhttps://docs.traefik.io/configuration/backends/docker/\n\nhttps://docs.traefik.io/user-guide/swarm-mode/\n\nWindows without working routing mesh: need publish-port mode (dnsrr) at it´s services, then Traefik has a problem: https://github.com/containous/traefik/issues/833\n\nhttps://github.com/moby/moby/issues/25016\n\nhttps://github.com/containous/traefik/issues/913\n\nhttps://stackoverflow.com/questions/45822412/docker-swarm-windows-worker-with-traefik-returns-gateway-timeout\n\n\n\n\n\n### Zero downtime deployment\n\nhttps://docs.docker.com/engine/swarm/swarm-tutorial/rolling-update/\n\nhttps://www.gesellix.net/post/zero-downtime-deployment-with-docker-stack-and-spring-boot/\n\n","funding_links":[],"categories":["vagrant","Ruby"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonashackt%2Fansible-windows-docker-springboot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjonashackt%2Fansible-windows-docker-springboot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonashackt%2Fansible-windows-docker-springboot/lists"}