├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── meta
└── main.yml
├── screenshots
├── 3_boxes.png
├── Windows_build_number_Docker_failing.png
├── Windows_build_number_Docker_working.png
├── all-apps-available-via-routing-mesh.png
├── curl-linux-container.png
├── docker-network-correct-nat-config.png
├── docker-service-inspect-app.png
├── docker-service-ls.png
├── docker-service-ps-app.png
├── docker-swarm-services-registered-eureka.png
├── docker-swarm-setup.png
├── first-docker-swarm-services-running-portainer.png
├── first-full-call-through-traefik-mixed-os-apps-incl-eureka-feign-soapui-client.png
├── first-successful-Linux-worker-join-with-ansible.png
├── first-successful-ansible-run-to-hybrid-linux-windows-machines.png
├── first-successful-app-call-through-traefik.png
├── first-successful-call-to-both-windows-and-linux-containers-through-traefik.png
├── first-successful-docker-swarm-join-with-ansible.png
├── first-successful-docker-swarm-join.png
├── first-successful-docker-windows-ingress-swarm-service.png
├── first-successful-push-into-registry.png
├── first-successful-stack-deploy.png
├── first-successful-traefik-service-deployment-incl-registered-apps.png
├── how-swarm-services-work.png
├── ingress-routing-mesh.png
├── portainer-swarm-visualizer.png
├── running-hybrid-os-docker-swarm-windows-linux-manager-and-windows-linux-worker-nodes.png
├── spring-boot-example-running-docker-windows-containers.png
├── spring-cloud-example-running-docker-windows-containers-docker-compose.png
├── spring-cloud-example-running-docker-windows-containers.png
├── windows-docker-network-architecture.png
└── working-build-nr-and-update-kb4048955-for-ingress-networking-docker-windows.png
├── step0-packer-windows-vagrantbox
├── README.md
├── ansible-windows-simple
│ ├── group_vars
│ │ └── windows-dev.yml
│ ├── hostsfile
│ └── windows-playbook.yml
├── automated_windows_installation.png
├── packerCommands.sh
├── scripts
│ ├── Autounattend.xml
│ ├── configure-ansible.ps1
│ ├── oracle-cert.cer
│ ├── server_1709
│ │ └── Autounattend.xml
│ ├── server_1803
│ │ └── Autounattend.xml
│ └── vm-guest-tools.bat
├── vagrantfile-windows_1709-multimachine.template
├── vagrantfile-windows_1803-multimachine.template
├── vagrantfile-windows_2016-multimachine.template
├── vagrantfile-windows_2016.template
└── windows_server_2016_docker.json
├── step1-prepare-docker-windows
├── build-springboot-oraclejre-nanoserver-image.yml
├── check-build-number.yml
├── group_vars
│ └── all.yml
├── hostsfile
├── install-docker-compose.yml
├── install-docker.yml
├── install-windows-container-features.yml
├── install-windows-updates.yml
├── playbookCommands.sh
├── prepare-docker-windows.yml
├── run-test-container.yml
└── templates
│ ├── Dockerfile-SpringBoot-OracleJRE-Nanoserver-1709.j2
│ ├── Dockerfile-SpringBoot-OracleJRE-Nanoserver-1803.j2
│ └── Dockerfile-SpringBoot-OracleJRE-Nanoserver.j2
├── step2-single-spring-boot-app
├── ansible-windows-docker-springboot.yml
├── group_vars
│ ├── all.yml
│ ├── ansible-windows-docker-springboot-dev.yml
│ └── ansible-windows-docker-springboot-qa.yml
├── hostsfile
├── playbookCommands.sh
└── templates
│ └── Dockerfile-SpringBoot-App.j2
├── step3-multiple-spring-boot-apps-docker-compose
├── ansible-windows-docker-springboot.yml
├── docker-compose-run-all-services.yml
├── group_vars
│ ├── all.yml
│ ├── ansible-windows-docker-springboot-dev.yml
│ └── ansible-windows-docker-springboot-qa.yml
├── hostsfile
├── playbookCommands.sh
├── spring-boot-app-health-check.yml
├── spring-boot-app-prepare.yml
└── templates
│ ├── Dockerfile-SpringBoot-App.j2
│ └── docker-compose.j2
├── step4-windows-linux-multimachine-vagrant-docker-swarm-setup
├── Vagrantfile
├── allow-http-docker-registry.yml
├── display-swarm-status.yml
├── group_vars
│ ├── all.yml
│ ├── linux.yml
│ ├── masterlinux.yml
│ ├── masterwindows.yml
│ ├── windows.yml
│ ├── workerlinux.yml
│ └── workerwindows.yml
├── hostsfile
├── initialize-docker-swarm.yml
├── initialize-swarm-and-join-all-nodes.yml
├── label-os-specific-nodes.yml
├── playbookCommands.sh
├── prepare-docker-linux.yml
├── prepare-docker-nodes.yml
├── prepare-firewalls-for-swarm.yml
├── run-portainer.yml
├── run-swarm-registry.yml
└── templates
│ └── daemon.j2
└── step5-deploy-multiple-spring-boot-apps-to-mixed-os-docker-swarm
├── build-and-deploy-apps-2-swarm.yml
├── deploy-services-swarm.yml
├── group_vars
├── all.yml
├── linux.yml
├── masterlinux.yml
├── masterwindows.yml
├── windows.yml
├── workerlinux.yml
└── workerwindows.yml
├── hostsfile
├── playbookCommands.sh
├── prepare-docker-images-linux.yml
├── prepare-docker-images-windows.yml
├── prepare-firewall-app-access.yml
├── spring-boot-app-health-check.yml
└── templates
├── Dockerfile-SpringBoot-Linux.j2
├── Dockerfile-SpringBoot-Windows.j2
└── docker-stack.j2
/.gitignore:
--------------------------------------------------------------------------------
1 | *.class
2 |
3 | # Package Files #
4 | *.jar
5 | *.war
6 | *.ear
7 |
8 | # Eclipse #
9 | .settings
10 | .project
11 | .classpath
12 | .studio
13 | target
14 |
15 | # Vagrant
16 | .vagrant
17 |
18 | # Apple #
19 | .DS_Store
20 |
21 | # Intellij #
22 | .idea
23 | *.iml
24 | *.log
25 |
26 | # Ansible
27 | *.retry
28 |
29 | # logback
30 | logback.out.xml
31 |
32 | # zips
33 | *.tar.gz
34 |
35 | # Vagrantboxes
36 | *.box
37 | step0-packer-windows-vagrantbox/Vagrantfile
38 | *.ISO
39 | step0-packer-windows-vagrantbox/packer_cache
40 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | ---
2 | language: python
3 | python: "2.7"
4 |
5 | # Use the new container infrastructure
6 | sudo: false
7 |
8 | # Install ansible
9 | addons:
10 | apt:
11 | packages:
12 | - python-pip
13 |
14 | install:
15 | # Install ansible
16 | - pip install ansible
17 |
18 | # Check ansible version
19 | - ansible --version
20 |
21 | # Create ansible.cfg with correct roles_path
22 | - printf '[defaults]\nroles_path=../' >ansible.cfg
23 |
24 | script:
25 | # Basic playbook syntax check
26 | - ansible-playbook -i hostsfile step1-prepare-docker-windows/prepare-docker-windows.yml --extra-vars "host=ansible-windows-docker-springboot-dev" --syntax-check
27 | - ansible-playbook -i hostsfile step2-single-spring-boot-app/ansible-windows-docker-springboot.yml --extra-vars "host=ansible-windows-docker-springboot-dev" --syntax-check
28 | - ansible-playbook -i hostsfile step3-multiple-spring-boot-apps-docker-compose/ansible-windows-docker-springboot.yml --extra-vars "host=ansible-windows-docker-springboot-dev" --syntax-check
29 | - ansible-playbook -i hostsfile step4-windows-linux-multimachine-vagrant-docker-swarm-setup/prepare-docker-nodes.yml --syntax-check
30 | - ansible-playbook -i hostsfile step4-windows-linux-multimachine-vagrant-docker-swarm-setup/initialize-docker-swarm.yml --syntax-check
31 | - ansible-playbook -i hostsfile step5-deploy-multiple-spring-boot-apps-to-mixed-os-docker-swarm/build-and-deploy-apps-2-swarm.yml --syntax-check
32 |
33 | notifications:
34 | webhooks: https://galaxy.ansible.com/api/v1/notifications/
35 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Jonas Hecht
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/meta/main.yml:
--------------------------------------------------------------------------------
1 | galaxy_info:
2 | author: Jonas Hecht
3 | description: Ansible playbook to deploy and run Spring Boot apps with Docker natively on Windows.
4 | # company: your company (optional)
5 |
6 | license: license (MIT)
7 |
8 | min_ansible_version: 2.3.0
9 |
10 | github_branch: release
11 |
12 | #
13 | # Below are all platforms currently available. Just uncomment
14 | # the ones that apply to your role. If you don't see your
15 | # platform on this list, let us know and we'll get it added!
16 | #
17 | platforms:
18 | #- name: EL
19 | # versions:
20 | # - all
21 | # - 5
22 | # - 6
23 | # - 7
24 | #- name: GenericUNIX
25 | # versions:
26 | # - all
27 | # - any
28 | #- name: OpenBSD
29 | # versions:
30 | # - all
31 | # - 5.6
32 | # - 5.7
33 | # - 5.8
34 | # - 5.9
35 | # - 6.0
36 | #- name: Fedora
37 | # versions:
38 | # - all
39 | # - 16
40 | # - 17
41 | # - 18
42 | # - 19
43 | # - 20
44 | # - 21
45 | # - 22
46 | # - 23
47 | #- name: opensuse
48 | # versions:
49 | # - all
50 | # - 12.1
51 | # - 12.2
52 | # - 12.3
53 | # - 13.1
54 | # - 13.2
55 | #- name: MacOSX
56 | # versions:
57 | # - all
58 | # - 10.10
59 | # - 10.11
60 | # - 10.12
61 | # - 10.7
62 | # - 10.8
63 | # - 10.9
64 | #- name: IOS
65 | # versions:
66 | # - all
67 | # - any
68 | #- name: Solaris
69 | # versions:
70 | # - all
71 | # - 10
72 | # - 11.0
73 | # - 11.1
74 | # - 11.2
75 | # - 11.3
76 | #- name: SmartOS
77 | # versions:
78 | # - all
79 | # - any
80 | #- name: eos
81 | # versions:
82 | # - all
83 | # - Any
84 | - name: Windows
85 | versions:
86 | - 10
87 | - 2016
88 | #- name: Amazon
89 | # versions:
90 | # - all
91 | # - 2013.03
92 | # - 2013.09
93 | #- name: GenericBSD
94 | # versions:
95 | # - all
96 | # - any
97 | #- name: Junos
98 | # versions:
99 | # - all
100 | # - any
101 | #- name: FreeBSD
102 | # versions:
103 | # - all
104 | # - 10.0
105 | # - 10.1
106 | # - 10.2
107 | # - 10.3
108 | # - 8.0
109 | # - 8.1
110 | # - 8.2
111 | # - 8.3
112 | # - 8.4
113 | # - 9.0
114 | # - 9.1
115 | # - 9.1
116 | # - 9.2
117 | # - 9.3
118 | #- name: Ubuntu
119 | # versions:
120 | # - all
121 | # - lucid
122 | # - maverick
123 | # - natty
124 | # - oneiric
125 | # - precise
126 | # - quantal
127 | # - raring
128 | # - saucy
129 | # - trusty
130 | # - utopic
131 | # - vivid
132 | # - wily
133 | # - xenial
134 | #- name: SLES
135 | # versions:
136 | # - all
137 | # - 10SP3
138 | # - 10SP4
139 | # - 11
140 | # - 11SP1
141 | # - 11SP2
142 | # - 11SP3
143 | # - 11SP4
144 | # - 12
145 | # - 12SP1
146 | #- name: GenericLinux
147 | # versions:
148 | # - all
149 | # - any
150 | #- name: NXOS
151 | # versions:
152 | # - all
153 | # - any
154 | #- name: Debian
155 | # versions:
156 | # - all
157 | # - etch
158 | # - jessie
159 | # - lenny
160 | # - sid
161 | # - squeeze
162 | # - stretch
163 | # - wheezy
164 |
165 | galaxy_tags:
166 |
167 | - windows
168 | - windowsserver
169 | - spring
170 | - springboot
171 | - java
172 | - java8
173 | - system
174 | - development
175 | - web
176 |
177 | dependencies: []
178 |
--------------------------------------------------------------------------------
/screenshots/3_boxes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jonashackt/ansible-windows-docker-springboot/614ce574de4a671e76bccf10a71416f675974e21/screenshots/3_boxes.png
--------------------------------------------------------------------------------
/screenshots/Windows_build_number_Docker_failing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jonashackt/ansible-windows-docker-springboot/614ce574de4a671e76bccf10a71416f675974e21/screenshots/Windows_build_number_Docker_failing.png
--------------------------------------------------------------------------------
/screenshots/Windows_build_number_Docker_working.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jonashackt/ansible-windows-docker-springboot/614ce574de4a671e76bccf10a71416f675974e21/screenshots/Windows_build_number_Docker_working.png
--------------------------------------------------------------------------------
/screenshots/all-apps-available-via-routing-mesh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jonashackt/ansible-windows-docker-springboot/614ce574de4a671e76bccf10a71416f675974e21/screenshots/all-apps-available-via-routing-mesh.png
--------------------------------------------------------------------------------
/screenshots/curl-linux-container.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jonashackt/ansible-windows-docker-springboot/614ce574de4a671e76bccf10a71416f675974e21/screenshots/curl-linux-container.png
--------------------------------------------------------------------------------
/screenshots/docker-network-correct-nat-config.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jonashackt/ansible-windows-docker-springboot/614ce574de4a671e76bccf10a71416f675974e21/screenshots/docker-network-correct-nat-config.png
--------------------------------------------------------------------------------
/screenshots/docker-service-inspect-app.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jonashackt/ansible-windows-docker-springboot/614ce574de4a671e76bccf10a71416f675974e21/screenshots/docker-service-inspect-app.png
--------------------------------------------------------------------------------
/screenshots/docker-service-ls.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jonashackt/ansible-windows-docker-springboot/614ce574de4a671e76bccf10a71416f675974e21/screenshots/docker-service-ls.png
--------------------------------------------------------------------------------
/screenshots/docker-service-ps-app.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jonashackt/ansible-windows-docker-springboot/614ce574de4a671e76bccf10a71416f675974e21/screenshots/docker-service-ps-app.png
--------------------------------------------------------------------------------
/screenshots/docker-swarm-services-registered-eureka.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jonashackt/ansible-windows-docker-springboot/614ce574de4a671e76bccf10a71416f675974e21/screenshots/docker-swarm-services-registered-eureka.png
--------------------------------------------------------------------------------
/screenshots/docker-swarm-setup.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jonashackt/ansible-windows-docker-springboot/614ce574de4a671e76bccf10a71416f675974e21/screenshots/docker-swarm-setup.png
--------------------------------------------------------------------------------
/screenshots/first-docker-swarm-services-running-portainer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jonashackt/ansible-windows-docker-springboot/614ce574de4a671e76bccf10a71416f675974e21/screenshots/first-docker-swarm-services-running-portainer.png
--------------------------------------------------------------------------------
/screenshots/first-full-call-through-traefik-mixed-os-apps-incl-eureka-feign-soapui-client.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jonashackt/ansible-windows-docker-springboot/614ce574de4a671e76bccf10a71416f675974e21/screenshots/first-full-call-through-traefik-mixed-os-apps-incl-eureka-feign-soapui-client.png
--------------------------------------------------------------------------------
/screenshots/first-successful-Linux-worker-join-with-ansible.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jonashackt/ansible-windows-docker-springboot/614ce574de4a671e76bccf10a71416f675974e21/screenshots/first-successful-Linux-worker-join-with-ansible.png
--------------------------------------------------------------------------------
/screenshots/first-successful-ansible-run-to-hybrid-linux-windows-machines.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jonashackt/ansible-windows-docker-springboot/614ce574de4a671e76bccf10a71416f675974e21/screenshots/first-successful-ansible-run-to-hybrid-linux-windows-machines.png
--------------------------------------------------------------------------------
/screenshots/first-successful-app-call-through-traefik.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jonashackt/ansible-windows-docker-springboot/614ce574de4a671e76bccf10a71416f675974e21/screenshots/first-successful-app-call-through-traefik.png
--------------------------------------------------------------------------------
/screenshots/first-successful-call-to-both-windows-and-linux-containers-through-traefik.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jonashackt/ansible-windows-docker-springboot/614ce574de4a671e76bccf10a71416f675974e21/screenshots/first-successful-call-to-both-windows-and-linux-containers-through-traefik.png
--------------------------------------------------------------------------------
/screenshots/first-successful-docker-swarm-join-with-ansible.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jonashackt/ansible-windows-docker-springboot/614ce574de4a671e76bccf10a71416f675974e21/screenshots/first-successful-docker-swarm-join-with-ansible.png
--------------------------------------------------------------------------------
/screenshots/first-successful-docker-swarm-join.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jonashackt/ansible-windows-docker-springboot/614ce574de4a671e76bccf10a71416f675974e21/screenshots/first-successful-docker-swarm-join.png
--------------------------------------------------------------------------------
/screenshots/first-successful-docker-windows-ingress-swarm-service.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jonashackt/ansible-windows-docker-springboot/614ce574de4a671e76bccf10a71416f675974e21/screenshots/first-successful-docker-windows-ingress-swarm-service.png
--------------------------------------------------------------------------------
/screenshots/first-successful-push-into-registry.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jonashackt/ansible-windows-docker-springboot/614ce574de4a671e76bccf10a71416f675974e21/screenshots/first-successful-push-into-registry.png
--------------------------------------------------------------------------------
/screenshots/first-successful-stack-deploy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jonashackt/ansible-windows-docker-springboot/614ce574de4a671e76bccf10a71416f675974e21/screenshots/first-successful-stack-deploy.png
--------------------------------------------------------------------------------
/screenshots/first-successful-traefik-service-deployment-incl-registered-apps.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jonashackt/ansible-windows-docker-springboot/614ce574de4a671e76bccf10a71416f675974e21/screenshots/first-successful-traefik-service-deployment-incl-registered-apps.png
--------------------------------------------------------------------------------
/screenshots/how-swarm-services-work.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jonashackt/ansible-windows-docker-springboot/614ce574de4a671e76bccf10a71416f675974e21/screenshots/how-swarm-services-work.png
--------------------------------------------------------------------------------
/screenshots/ingress-routing-mesh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jonashackt/ansible-windows-docker-springboot/614ce574de4a671e76bccf10a71416f675974e21/screenshots/ingress-routing-mesh.png
--------------------------------------------------------------------------------
/screenshots/portainer-swarm-visualizer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jonashackt/ansible-windows-docker-springboot/614ce574de4a671e76bccf10a71416f675974e21/screenshots/portainer-swarm-visualizer.png
--------------------------------------------------------------------------------
/screenshots/running-hybrid-os-docker-swarm-windows-linux-manager-and-windows-linux-worker-nodes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jonashackt/ansible-windows-docker-springboot/614ce574de4a671e76bccf10a71416f675974e21/screenshots/running-hybrid-os-docker-swarm-windows-linux-manager-and-windows-linux-worker-nodes.png
--------------------------------------------------------------------------------
/screenshots/spring-boot-example-running-docker-windows-containers.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jonashackt/ansible-windows-docker-springboot/614ce574de4a671e76bccf10a71416f675974e21/screenshots/spring-boot-example-running-docker-windows-containers.png
--------------------------------------------------------------------------------
/screenshots/spring-cloud-example-running-docker-windows-containers-docker-compose.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jonashackt/ansible-windows-docker-springboot/614ce574de4a671e76bccf10a71416f675974e21/screenshots/spring-cloud-example-running-docker-windows-containers-docker-compose.png
--------------------------------------------------------------------------------
/screenshots/spring-cloud-example-running-docker-windows-containers.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jonashackt/ansible-windows-docker-springboot/614ce574de4a671e76bccf10a71416f675974e21/screenshots/spring-cloud-example-running-docker-windows-containers.png
--------------------------------------------------------------------------------
/screenshots/windows-docker-network-architecture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jonashackt/ansible-windows-docker-springboot/614ce574de4a671e76bccf10a71416f675974e21/screenshots/windows-docker-network-architecture.png
--------------------------------------------------------------------------------
/screenshots/working-build-nr-and-update-kb4048955-for-ingress-networking-docker-windows.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jonashackt/ansible-windows-docker-springboot/614ce574de4a671e76bccf10a71416f675974e21/screenshots/working-build-nr-and-update-kb4048955-for-ingress-networking-docker-windows.png
--------------------------------------------------------------------------------
/step0-packer-windows-vagrantbox/README.md:
--------------------------------------------------------------------------------
1 | Ansible ready & packer.io build Windows Server 2016 Vagrant box
2 | ======================================================================================
3 | #### packer template and some Powershell scripts to build a Ansible-ready Windows Server 2016 Vagrant box (as alternative to the [Vagrant box with Windows 10 from the Microsoft Edge developer site](https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/#downloads), which doesn´t work with Docker because of the wrong build number)
4 |
5 | The box has Ansible-connectitity "turned on" (so WinRM, Firewall settings, Network settings and so on) and is a working basis for a Docker Windows Container installment.
6 |
7 | It borrowes bits from https://github.com/StefanScherer/docker-windows-box and https://github.com/StefanScherer/packer-windows, which forks https://github.com/joefitzgerald/packer-windows itself. If you like to dig deeper into the myriads of configuration options, have a look into Stefan Scherers GitHub repositories. kudos go to [Stefan](https://github.com/StefanScherer) und [Joe](Joe Fitzgerald) - and not to forget the great [hashicorp tools](https://www.hashicorp.com/).
8 |
9 | This setup will install Windows into a Virtual Box image completely without user interaction:
10 |
11 | 
--------------------------------------------------------------------------------
/step0-packer-windows-vagrantbox/ansible-windows-simple/group_vars/windows-dev.yml:
--------------------------------------------------------------------------------
1 | # http://docs.ansible.com/ansible/intro_windows.html#windows-how-does-it-work
2 |
3 | ansible_user: vagrant
4 | ansible_password: vagrant
5 | ansible_port: 55986 # not 5986, as we would use for non-virtualized environments
6 | ansible_connection: winrm
7 |
8 | # The following is necessary for Python 2.7.9+ when using default WinRM self-signed certificates:
9 | ansible_winrm_server_cert_validation: ignore
--------------------------------------------------------------------------------
/step0-packer-windows-vagrantbox/ansible-windows-simple/hostsfile:
--------------------------------------------------------------------------------
1 | [windows-dev]
2 | 127.0.0.1
--------------------------------------------------------------------------------
/step0-packer-windows-vagrantbox/ansible-windows-simple/windows-playbook.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - hosts: "{{host}}"
3 |
4 | tasks:
5 | - name: Install firefox
6 | win_chocolatey:
7 | name: firefox
--------------------------------------------------------------------------------
/step0-packer-windows-vagrantbox/automated_windows_installation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jonashackt/ansible-windows-docker-springboot/614ce574de4a671e76bccf10a71416f675974e21/step0-packer-windows-vagrantbox/automated_windows_installation.png
--------------------------------------------------------------------------------
/step0-packer-windows-vagrantbox/packerCommands.sh:
--------------------------------------------------------------------------------
1 |
2 | # Run Packer build with Windows Server 2016
3 | packer build -var iso_url=Windows_Server_2016_Datacenter_EVAL_en-us_14393_refresh.ISO -var iso_checksum=70721288bbcdfe3239d8f8c0fae55f1f windows_server_2016_docker.json
4 |
5 | # add it to local Vagrant Boxes
6 | vagrant box add --name windows_2016_multimachine windows_2016_docker_multimachine_virtualbox.box
7 |
8 |
9 | # Run packer build with Windows Server 1709
10 | packer build -var iso_url=en_windows_server_version_1709_x64_dvd_100090904.iso -var iso_checksum=7c73ce30c3975652262f794fc35127b5 -var template_url=vagrantfile-windows_1709-multimachine.template -var box_output_prefix=windows_1709_docker_multimachine windows_server_2016_docker.json
11 |
12 | # add it to local Vagrant Boxes
13 | vagrant box add --name windows_1709_docker_multimachine windows_1709_docker_multimachine_virtualbox.box
14 |
15 |
16 | # Run packer build with Windows Server 1803
17 | packer 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
18 |
19 | # add it to local Vagrant Boxes
20 | vagrant box add --name windows_1803_docker_multimachine windows_1803_docker_multimachine_virtualbox.box
21 |
22 |
--------------------------------------------------------------------------------
/step0-packer-windows-vagrantbox/scripts/Autounattend.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | 1
11 | Primary
12 | true
13 |
14 |
15 |
16 |
17 | false
18 | NTFS
19 | C
20 | 1
21 | 1
22 |
23 |
24 |
25 | 0
26 | true
27 |
28 | OnError
29 |
30 |
31 | true
32 | Vagrant Administrator
33 | Vagrant Inc.
34 |
35 |
47 |
48 |
49 | NPPR9-FWDCX-D2C8J-H872K-2YT43
50 | Never
51 |
52 |
53 |
54 |
55 |
56 | 0
57 | 1
58 |
59 | OnError
60 | false
61 |
62 |
63 | /IMAGE/NAME
64 | Windows Server 2016 SERVERSTANDARD
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 | en-US
73 |
74 | en-US
75 | en-US
76 | en-US
77 | en-US
78 | en-US
79 |
80 |
81 |
82 |
83 | false
84 |
85 |
86 |
87 |
88 |
89 |
90 | vagrant
91 | true
92 |
93 |
94 |
95 |
96 | vagrant
97 | true
98 |
99 | Vagrant User
100 | vagrant
101 | administrators
102 | vagrant
103 |
104 |
105 |
106 |
107 | true
108 | true
109 | Home
110 | 1
111 |
112 |
113 |
114 | vagrant
115 | true
116 |
117 | vagrant
118 | true
119 |
120 |
121 |
122 | cmd.exe /c powershell -Command "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force"
123 | Set Execution Policy 64 Bit
124 | 1
125 | true
126 |
127 |
128 | C:\Windows\SysWOW64\cmd.exe /c powershell -Command "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force"
129 | Set Execution Policy 32 Bit
130 | 2
131 | true
132 |
133 |
134 | cmd.exe /c reg add "HKLM\System\CurrentControlSet\Control\Network\NewNetworkWindowOff"
135 | Network prompt
136 | 3
137 | true
138 |
139 |
140 | cmd.exe /c winrm quickconfig -q
141 | winrm quickconfig -q
142 | 5
143 | true
144 |
145 |
146 | cmd.exe /c winrm quickconfig -transport:http
147 | winrm quickconfig -transport:http
148 | 6
149 | true
150 |
151 |
152 | cmd.exe /c winrm set winrm/config @{MaxTimeoutms="1800000"}
153 | Win RM MaxTimoutms
154 | 7
155 | true
156 |
157 |
158 | cmd.exe /c winrm set winrm/config/winrs @{MaxMemoryPerShellMB="800"}
159 | Win RM MaxMemoryPerShellMB
160 | 8
161 | true
162 |
163 |
164 | cmd.exe /c winrm set winrm/config/service @{AllowUnencrypted="true"}
165 | Win RM AllowUnencrypted
166 | 9
167 | true
168 |
169 |
170 | cmd.exe /c winrm set winrm/config/service/auth @{Basic="true"}
171 | Win RM auth Basic
172 | 10
173 | true
174 |
175 |
176 | cmd.exe /c winrm set winrm/config/client/auth @{Basic="true"}
177 | Win RM client auth Basic
178 | 11
179 | true
180 |
181 |
182 | cmd.exe /c winrm set winrm/config/listener?Address=*+Transport=HTTP @{Port="5985"}
183 | Win RM listener Address/Port
184 | 12
185 | true
186 |
187 |
188 | cmd.exe /c netsh advfirewall firewall set rule group="remote administration" new enable=yes
189 | Win RM adv firewall enable
190 | 13
191 | true
192 |
193 |
194 | cmd.exe /c netsh firewall add portopening TCP 5985 "Port 5985"
195 | Win RM port open
196 | 14
197 | true
198 |
199 |
200 | cmd.exe /c net stop winrm
201 | Stop Win RM Service
202 | 15
203 | true
204 |
205 |
206 | cmd.exe /c sc config winrm start= auto
207 | Win RM Autostart
208 | 16
209 | true
210 |
211 |
212 | cmd.exe /c net start winrm
213 | Start Win RM Service
214 | 17
215 | true
216 |
217 |
218 | %SystemRoot%\System32\reg.exe ADD HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ /v HideFileExt /t REG_DWORD /d 0 /f
219 | 18
220 | Show file extensions in Explorer
221 |
222 |
223 | %SystemRoot%\System32\reg.exe ADD HKCU\Console /v QuickEdit /t REG_DWORD /d 1 /f
224 | 19
225 | Enable QuickEdit mode
226 |
227 |
228 | %SystemRoot%\System32\reg.exe ADD HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ /v Start_ShowRun /t REG_DWORD /d 1 /f
229 | 20
230 | Show Run command in Start Menu
231 |
232 |
233 | %SystemRoot%\System32\reg.exe ADD HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ /v StartMenuAdminTools /t REG_DWORD /d 1 /f
234 | 21
235 | Show Administrative Tools in Start Menu
236 |
237 |
238 | %SystemRoot%\System32\reg.exe ADD HKLM\SYSTEM\CurrentControlSet\Control\Power\ /v HibernateFileSizePercent /t REG_DWORD /d 0 /f
239 | 22
240 | Zero Hibernation File
241 |
242 |
243 | %SystemRoot%\System32\reg.exe ADD HKLM\SYSTEM\CurrentControlSet\Control\Power\ /v HibernateEnabled /t REG_DWORD /d 0 /f
244 | 23
245 | Disable Hibernation Mode
246 |
247 |
248 | cmd.exe /c wmic useraccount where "name='vagrant'" set PasswordExpires=FALSE
249 | 24
250 | Disable password expiration for vagrant user
251 |
252 |
253 | false
254 |
255 |
256 |
257 |
258 |
259 | false
260 |
261 |
262 | vagrant-10
263 | Pacific Standard Time
264 |
265 |
266 |
267 | true
268 |
269 |
270 |
271 |
272 |
--------------------------------------------------------------------------------
/step0-packer-windows-vagrantbox/scripts/configure-ansible.ps1:
--------------------------------------------------------------------------------
1 | iwr https://raw.githubusercontent.com/ansible/ansible/devel/examples/scripts/ConfigureRemotingForAnsible.ps1 -UseBasicParsing | iex
2 |
--------------------------------------------------------------------------------
/step0-packer-windows-vagrantbox/scripts/oracle-cert.cer:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jonashackt/ansible-windows-docker-springboot/614ce574de4a671e76bccf10a71416f675974e21/step0-packer-windows-vagrantbox/scripts/oracle-cert.cer
--------------------------------------------------------------------------------
/step0-packer-windows-vagrantbox/scripts/server_1709/Autounattend.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | 1
11 | Primary
12 | true
13 |
14 |
15 |
16 |
17 | false
18 | NTFS
19 | C
20 | 1
21 | 1
22 |
23 |
24 |
25 | 0
26 | true
27 |
28 | OnError
29 |
30 |
31 | true
32 | Vagrant Administrator
33 | Vagrant Inc.
34 |
35 |
47 |
48 |
49 | NPPR9-FWDCX-D2C8J-H872K-2YT43
50 | Never
51 |
52 |
53 |
54 |
55 |
56 | 0
57 | 2
58 |
59 |
60 |
61 | /IMAGE/NAME
62 | Windows Server 2016 SERVERDATACENTERACORE
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | en-US
71 |
72 | en-US
73 | en-US
74 | en-US
75 | en-US
76 | en-US
77 |
78 |
79 |
80 |
81 | false
82 |
83 |
84 |
85 |
86 |
87 |
88 | vagrant
89 | true
90 |
91 |
92 |
93 |
94 | vagrant
95 | true
96 |
97 | Vagrant User
98 | vagrant
99 | administrators
100 | vagrant
101 |
102 |
103 |
104 |
105 | true
106 | true
107 | Home
108 | 1
109 |
110 |
111 |
112 | vagrant
113 | true
114 |
115 | vagrant
116 | true
117 |
118 |
119 |
120 | cmd.exe /c powershell -Command "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force"
121 | Set Execution Policy 64 Bit
122 | 1
123 | true
124 |
125 |
126 | C:\Windows\SysWOW64\cmd.exe /c powershell -Command "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force"
127 | Set Execution Policy 32 Bit
128 | 2
129 | true
130 |
131 |
132 | cmd.exe /c reg add "HKLM\System\CurrentControlSet\Control\Network\NewNetworkWindowOff"
133 | Network prompt
134 | 3
135 | true
136 |
137 |
138 | cmd.exe /c winrm quickconfig -q
139 | winrm quickconfig -q
140 | 5
141 | true
142 |
143 |
144 | cmd.exe /c winrm quickconfig -transport:http
145 | winrm quickconfig -transport:http
146 | 6
147 | true
148 |
149 |
150 | cmd.exe /c winrm set winrm/config @{MaxTimeoutms="1800000"}
151 | Win RM MaxTimoutms
152 | 7
153 | true
154 |
155 |
156 | cmd.exe /c winrm set winrm/config/winrs @{MaxMemoryPerShellMB="800"}
157 | Win RM MaxMemoryPerShellMB
158 | 8
159 | true
160 |
161 |
162 | cmd.exe /c winrm set winrm/config/service @{AllowUnencrypted="true"}
163 | Win RM AllowUnencrypted
164 | 9
165 | true
166 |
167 |
168 | cmd.exe /c winrm set winrm/config/service/auth @{Basic="true"}
169 | Win RM auth Basic
170 | 10
171 | true
172 |
173 |
174 | cmd.exe /c winrm set winrm/config/client/auth @{Basic="true"}
175 | Win RM client auth Basic
176 | 11
177 | true
178 |
179 |
180 | cmd.exe /c winrm set winrm/config/listener?Address=*+Transport=HTTP @{Port="5985"}
181 | Win RM listener Address/Port
182 | 12
183 | true
184 |
185 |
186 | cmd.exe /c netsh advfirewall firewall set rule group="remote administration" new enable=yes
187 | Win RM adv firewall enable
188 | 13
189 | true
190 |
191 |
192 | cmd.exe /c netsh firewall add portopening TCP 5985 "Port 5985"
193 | Win RM port open
194 | 14
195 | true
196 |
197 |
198 | cmd.exe /c net stop winrm
199 | Stop Win RM Service
200 | 15
201 | true
202 |
203 |
204 | cmd.exe /c sc config winrm start= auto
205 | Win RM Autostart
206 | 16
207 | true
208 |
209 |
210 | cmd.exe /c net start winrm
211 | Start Win RM Service
212 | 17
213 | true
214 |
215 |
216 | %SystemRoot%\System32\reg.exe ADD HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ /v HideFileExt /t REG_DWORD /d 0 /f
217 | 18
218 | Show file extensions in Explorer
219 |
220 |
221 | %SystemRoot%\System32\reg.exe ADD HKCU\Console /v QuickEdit /t REG_DWORD /d 1 /f
222 | 19
223 | Enable QuickEdit mode
224 |
225 |
226 | %SystemRoot%\System32\reg.exe ADD HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ /v Start_ShowRun /t REG_DWORD /d 1 /f
227 | 20
228 | Show Run command in Start Menu
229 |
230 |
231 | %SystemRoot%\System32\reg.exe ADD HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ /v StartMenuAdminTools /t REG_DWORD /d 1 /f
232 | 21
233 | Show Administrative Tools in Start Menu
234 |
235 |
236 | %SystemRoot%\System32\reg.exe ADD HKLM\SYSTEM\CurrentControlSet\Control\Power\ /v HibernateFileSizePercent /t REG_DWORD /d 0 /f
237 | 22
238 | Zero Hibernation File
239 |
240 |
241 | %SystemRoot%\System32\reg.exe ADD HKLM\SYSTEM\CurrentControlSet\Control\Power\ /v HibernateEnabled /t REG_DWORD /d 0 /f
242 | 23
243 | Disable Hibernation Mode
244 |
245 |
246 | cmd.exe /c wmic useraccount where "name='vagrant'" set PasswordExpires=FALSE
247 | 24
248 | Disable password expiration for vagrant user
249 |
250 |
251 | false
252 |
253 |
254 |
255 |
256 |
257 | false
258 |
259 | vagrant-1709
260 | Pacific Standard Time
261 |
262 |
263 |
264 | true
265 |
266 |
267 | false
268 | false
269 |
270 |
271 | true
272 |
273 |
274 | true
275 |
276 |
277 |
278 |
279 |
--------------------------------------------------------------------------------
/step0-packer-windows-vagrantbox/scripts/server_1803/Autounattend.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | en-US
7 |
8 | en-US
9 | en-US
10 | en-US
11 | en-US
12 | en-US
13 |
14 |
15 |
16 |
17 |
18 |
19 | Primary
20 | 1
21 | 350
22 |
23 |
24 | 2
25 | Primary
26 | true
27 |
28 |
29 |
30 |
31 | true
32 | NTFS
33 |
34 | 1
35 | 1
36 |
37 |
38 | NTFS
39 |
40 | C
41 | 2
42 | 2
43 |
44 |
45 | 0
46 | true
47 |
48 |
49 |
50 |
51 |
52 |
53 | /IMAGE/NAME
54 | Windows Server 2016 SERVERDATACENTERACORE
55 |
56 |
57 |
58 | 0
59 | 2
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 | OnError
68 |
69 | true
70 | Vagrant
71 | Vagrant
72 |
73 |
74 |
75 |
76 |
77 |
78 | false
79 |
80 | vagrant-1803
81 | Pacific Standard Time
82 |
83 |
84 |
85 | true
86 |
87 |
88 | false
89 | false
90 |
91 |
92 | true
93 |
94 |
95 | true
96 |
97 |
98 |
99 |
100 |
101 |
102 | vagrant
103 | true
104 |
105 | true
106 | vagrant
107 |
108 |
109 |
110 | cmd.exe /c powershell -Command "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force"
111 | Set Execution Policy 64 Bit
112 | 1
113 | true
114 |
115 |
116 | C:\Windows\SysWOW64\cmd.exe /c powershell -Command "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force"
117 | Set Execution Policy 32 Bit
118 | 2
119 | true
120 |
121 |
122 | C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File a:\disable-winrm.ps1
123 | Disable WinRM
124 | 3
125 | true
126 |
127 |
128 | %SystemRoot%\System32\reg.exe ADD HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ /v HideFileExt /t REG_DWORD /d 0 /f
129 | 4
130 | Show file extensions in Explorer
131 |
132 |
133 | %SystemRoot%\System32\reg.exe ADD HKCU\Console /v QuickEdit /t REG_DWORD /d 1 /f
134 | 5
135 | Enable QuickEdit mode
136 |
137 |
138 | %SystemRoot%\System32\reg.exe ADD HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ /v Start_ShowRun /t REG_DWORD /d 1 /f
139 | 6
140 | Show Run command in Start Menu
141 |
142 |
143 | %SystemRoot%\System32\reg.exe ADD HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ /v StartMenuAdminTools /t REG_DWORD /d 1 /f
144 | 7
145 | Show Administrative Tools in Start Menu
146 |
147 |
148 | %SystemRoot%\System32\reg.exe ADD HKLM\SYSTEM\CurrentControlSet\Control\Power\ /v HibernateFileSizePercent /t REG_DWORD /d 0 /f
149 | 8
150 | Zero Hibernation File
151 |
152 |
153 | %SystemRoot%\System32\reg.exe ADD HKLM\SYSTEM\CurrentControlSet\Control\Power\ /v HibernateEnabled /t REG_DWORD /d 0 /f
154 | 9
155 | Disable Hibernation Mode
156 |
157 |
158 | cmd.exe /c wmic useraccount where "name='vagrant'" set PasswordExpires=FALSE
159 | 10
160 | Disable password expiration for vagrant user
161 |
162 |
163 |
164 | cmd.exe /c winrm quickconfig -q
165 | winrm quickconfig -q
166 | 5
167 | true
168 |
169 |
170 | cmd.exe /c winrm quickconfig -transport:http
171 | winrm quickconfig -transport:http
172 | 6
173 | true
174 |
175 |
176 | cmd.exe /c winrm set winrm/config @{MaxTimeoutms="1800000"}
177 | Win RM MaxTimoutms
178 | 7
179 | true
180 |
181 |
182 | cmd.exe /c winrm set winrm/config/winrs @{MaxMemoryPerShellMB="800"}
183 | Win RM MaxMemoryPerShellMB
184 | 8
185 | true
186 |
187 |
188 | cmd.exe /c winrm set winrm/config/service @{AllowUnencrypted="true"}
189 | Win RM AllowUnencrypted
190 | 9
191 | true
192 |
193 |
194 | cmd.exe /c winrm set winrm/config/service/auth @{Basic="true"}
195 | Win RM auth Basic
196 | 10
197 | true
198 |
199 |
200 | cmd.exe /c winrm set winrm/config/client/auth @{Basic="true"}
201 | Win RM client auth Basic
202 | 11
203 | true
204 |
205 |
206 | cmd.exe /c winrm set winrm/config/listener?Address=*+Transport=HTTP @{Port="5985"}
207 | Win RM listener Address/Port
208 | 12
209 | true
210 |
211 |
212 | cmd.exe /c netsh advfirewall firewall set rule group="remote administration" new enable=yes
213 | Win RM adv firewall enable
214 | 13
215 | true
216 |
217 |
218 | cmd.exe /c netsh firewall add portopening TCP 5985 "Port 5985"
219 | Win RM port open
220 | 14
221 | true
222 |
223 |
224 | cmd.exe /c net stop winrm
225 | Stop Win RM Service
226 | 15
227 | true
228 |
229 |
230 | cmd.exe /c sc config winrm start= auto
231 | Win RM Autostart
232 | 16
233 | true
234 |
235 |
236 | cmd.exe /c net start winrm
237 | Start Win RM Service
238 | 17
239 | true
240 |
241 |
242 |
243 |
244 |
245 | true
246 | true
247 | true
248 | true
249 | true
250 | Home
251 | 1
252 |
253 |
254 |
255 | vagrant
256 | true
257 |
258 |
259 |
260 |
261 | vagrant
262 | true
263 |
264 | administrators
265 | Vagrant
266 | vagrant
267 | Vagrant User
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 | false
277 |
278 |
279 |
280 |
--------------------------------------------------------------------------------
/step0-packer-windows-vagrantbox/scripts/vm-guest-tools.bat:
--------------------------------------------------------------------------------
1 | :: Install 7zip
2 | if not exist "C:\Windows\Temp\7z920-x64.msi" (
3 | powershell -Command "(New-Object System.Net.WebClient).DownloadFile('http://www.7-zip.org/a/7z920-x64.msi', 'C:\Windows\Temp\7z920-x64.msi')" ' }} container_ip.txt"
48 |
49 | - name: Get the Docker Container´s internal IP address from the temporary txt-file (we have to do this because of templating problems, see http://stackoverflow.com/a/32279729/4964553)
50 | win_shell: cat container_ip.txt
51 | register: win_shell_txt_return
52 |
53 | - name: Define the IP as variable
54 | set_fact:
55 | docker_container_ip: "{{ win_shell_txt_return.stdout.splitlines()[0] }}"
56 |
57 | - debug:
58 | msg: "Your Docker Container has the internal IP {{ docker_container_ip }} --> Let´s do a health-check against this URI: 'http://{{ docker_container_ip }}:{{app_port}}/health'"
59 |
60 | - name: Sadly the first win_uri call responds with non-correctly filled fields - so we do a second one & ignore this error
61 | win_uri:
62 | url: "http://{{ docker_container_ip }}:{{app_port}}/health"
63 | method: GET
64 | headers:
65 | Accept: application/json
66 | register: health_result_bad
67 | until: health_result_bad.status_code == 200
68 | ignore_errors: yes
69 |
70 | - name:
71 | debug:
72 | msg: "Our first check gave us: {{ health_result_bad }}"
73 |
74 | - name: Wait until our Spring Boot app is up & running
75 | win_uri:
76 | url: "http://{{ docker_container_ip }}:{{app_port}}/health"
77 | method: GET
78 | headers:
79 | Accept: application/json
80 | register: health_result
81 | until: health_result.status_code == 200
82 | retries: 30
83 | delay: 20
84 | ignore_errors: yes
--------------------------------------------------------------------------------
/step2-single-spring-boot-app/group_vars/all.yml:
--------------------------------------------------------------------------------
1 | # http://docs.ansible.com/ansible/intro_windows.html#windows-how-does-it-work
2 |
3 | ansible_port: 55986 # not 5986, as we would use for non-virtualized environments
4 | ansible_connection: winrm
5 |
6 | # The following is necessary for Python 2.7.9+ when using default WinRM self-signed certificates:
7 | ansible_winrm_server_cert_validation: ignore
--------------------------------------------------------------------------------
/step2-single-spring-boot-app/group_vars/ansible-windows-docker-springboot-dev.yml:
--------------------------------------------------------------------------------
1 | # http://docs.ansible.com/ansible/intro_windows.html#windows-how-does-it-work
2 |
3 | ansible_user: vagrant
4 | ansible_password: vagrant
--------------------------------------------------------------------------------
/step2-single-spring-boot-app/group_vars/ansible-windows-docker-springboot-qa.yml:
--------------------------------------------------------------------------------
1 | # http://docs.ansible.com/ansible/intro_windows.html#windows-how-does-it-work
2 |
3 | ansible_user: vagrant
4 | ansible_password: vagrant
--------------------------------------------------------------------------------
/step2-single-spring-boot-app/hostsfile:
--------------------------------------------------------------------------------
1 | [ansible-windows-docker-springboot-dev]
2 | 127.0.0.1
3 |
4 | [ansible-windows-docker-springboot-qa]
5 | 127.0.0.1
--------------------------------------------------------------------------------
/step2-single-spring-boot-app/playbookCommands.sh:
--------------------------------------------------------------------------------
1 |
2 | # Run Spring Boot App on Docker Windows
3 | ansible-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"
4 |
5 |
--------------------------------------------------------------------------------
/step2-single-spring-boot-app/templates/Dockerfile-SpringBoot-App.j2:
--------------------------------------------------------------------------------
1 | #jinja2: newline_sequence:'\r\n'
2 | FROM springboot-oraclejre-nanoserver:latest
3 |
4 | MAINTAINER Jonas Hecht
5 |
6 | # Expose the apps Port
7 | EXPOSE {{app_port}}
8 |
9 | # Add Spring Boot app.jar to Container
10 | ADD {{app_name}}.jar app.jar
11 |
12 | # Fire up our Spring Boot app by default
13 | CMD ["java.exe", "-jar app.jar --server.port={{app_port}}"]
14 |
15 |
--------------------------------------------------------------------------------
/step3-multiple-spring-boot-apps-docker-compose/ansible-windows-docker-springboot.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - hosts: "{{host}}"
3 | vars:
4 | base_path: "C:\\springboot"
5 | services:
6 | - name: zuul-edgeservice
7 | path_to_jar: "../../cxf-spring-cloud-netflix-docker/zuul-edgeservice/target/zuul-edgeservice-0.0.1-SNAPSHOT.jar"
8 | port: 8080
9 | map_to_same_port_on_host: true
10 | service_registry_name: eureka-serviceregistry
11 |
12 | - name: eureka-serviceregistry
13 | path_to_jar: "../../cxf-spring-cloud-netflix-docker/eureka-serviceregistry/target/eureka-serviceregistry-0.0.1-SNAPSHOT.jar"
14 | port: 8761
15 | map_to_same_port_on_host: true
16 | service_registry_name: eureka-serviceregistry-second
17 |
18 | - name: eureka-serviceregistry-second
19 | path_to_jar: "../../cxf-spring-cloud-netflix-docker/eureka-serviceregistry/target/eureka-serviceregistry-0.0.1-SNAPSHOT.jar"
20 | port: 8761
21 | service_registry_name: eureka-serviceregistry
22 |
23 | - name: weatherbackend
24 | path_to_jar: "../../cxf-spring-cloud-netflix-docker/weatherbackend/target/weatherbackend-0.0.1-SNAPSHOT.jar"
25 | port: 8090
26 | service_registry_name: eureka-serviceregistry-second
27 |
28 | - name: weatherservice
29 | path_to_jar: "../../cxf-spring-cloud-netflix-docker/weatherservice/target/weatherservice-0.0.1-SNAPSHOT.jar"
30 | port: 8095
31 | service_registry_name: eureka-serviceregistry
32 |
33 | tasks:
34 | - name: Create base directory C:\springboot, if not there
35 | win_file: path={{base_path}} state=directory
36 |
37 | - name: Preparing the Spring Boot App´s Files for later docker-compose run
38 | include: spring-boot-app-prepare.yml
39 | with_items: "{{ vars.services }}"
40 |
41 | - name: Run all Services with Docker Compose
42 | include: docker-compose-run-all-services.yml
43 |
44 | - name: Do healthchecks for all services
45 | include: spring-boot-app-health-check.yml
46 | with_items: "{{ vars.services }}"
--------------------------------------------------------------------------------
/step3-multiple-spring-boot-apps-docker-compose/docker-compose-run-all-services.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Template docker-compose.yml to directory C:\spring-boot
3 | win_template:
4 | src: "templates/docker-compose.j2"
5 | dest: "{{base_path}}\\docker-compose.yml"
6 |
7 | - name: Stop all Docker containers (if there)
8 | win_shell: docker-compose --project-name springboot stop
9 | args:
10 | chdir: "{{base_path}}"
11 | ignore_errors: yes
12 |
13 | - name: Remove all Docker containers (if there)
14 | win_shell: docker-compose --project-name springboot rm -f
15 | args:
16 | chdir: "{{base_path}}"
17 | ignore_errors: yes
18 |
19 | - name: Remove all Services Docker images - just to be 100% save, that everything is build from the ground up
20 | win_shell: docker-compose --project-name springboot down --rmi all
21 | args:
22 | chdir: "{{base_path}}"
23 | ignore_errors: yes
24 |
25 | - name: (Re-)Build all Docker images
26 | win_shell: docker-compose build
27 | args:
28 | chdir: "{{base_path}}"
29 | ignore_errors: yes
30 |
31 | # As we later need to know our container's names for healthchecking but also want to be able to scale out, we're not able to use
32 | # containername feature https://docs.docker.com/compose/compose-file/#containername
33 | # But there's help! With docker-compose --project-name a CustomContainerNameBeginning (https://github.com/docker/compose/issues/3722)
34 | # we'll know exactly the names of our containers, which are springboot_service.name_1 - like springboot_weatherservice_1
35 | - name: Run all Docker containers
36 | win_shell: docker-compose --project-name springboot up -d
37 | args:
38 | chdir: "{{base_path}}"
39 | register: first_compose_up_run_result
40 | ignore_errors: yes
41 |
42 | # Sadly there are situations, where the first attempt to do a docker-compose up will fail for only some of our services
43 | # with this error: 'failed to create endpoint app_xyz_1 on network nat: HNS failed with error : Unspecified error'
44 | # But as we want to have them all running, simply giving the docker-compose a second 'up' mostly fixes the problem
45 | - name: If one container failed at startup, try to run it again (e.g. with 'failed to create endpoint app_xyz_1 on network nat .. HNS failed with error .. Unspecified error')
46 | win_shell: docker-compose --project-name springboot up -d
47 | args:
48 | chdir: "{{base_path}}"
49 | when: first_compose_up_run_result|failed
50 | ignore_errors: yes
--------------------------------------------------------------------------------
/step3-multiple-spring-boot-apps-docker-compose/group_vars/all.yml:
--------------------------------------------------------------------------------
1 | # http://docs.ansible.com/ansible/intro_windows.html#windows-how-does-it-work
2 |
3 | ansible_port: 55986 # not 5986, as we would use for non-virtualized environments
4 | ansible_connection: winrm
5 |
6 | # The following is necessary for Python 2.7.9+ when using default WinRM self-signed certificates:
7 | ansible_winrm_server_cert_validation: ignore
--------------------------------------------------------------------------------
/step3-multiple-spring-boot-apps-docker-compose/group_vars/ansible-windows-docker-springboot-dev.yml:
--------------------------------------------------------------------------------
1 | # http://docs.ansible.com/ansible/intro_windows.html#windows-how-does-it-work
2 |
3 | ansible_user: vagrant
4 | ansible_password: vagrant
--------------------------------------------------------------------------------
/step3-multiple-spring-boot-apps-docker-compose/group_vars/ansible-windows-docker-springboot-qa.yml:
--------------------------------------------------------------------------------
1 | # http://docs.ansible.com/ansible/intro_windows.html#windows-how-does-it-work
2 |
3 | ansible_user: vagrant
4 | ansible_password: vagrant
--------------------------------------------------------------------------------
/step3-multiple-spring-boot-apps-docker-compose/hostsfile:
--------------------------------------------------------------------------------
1 | [ansible-windows-docker-springboot-dev]
2 | 127.0.0.1
3 |
4 | [ansible-windows-docker-springboot-qa]
5 | 127.0.0.1
--------------------------------------------------------------------------------
/step3-multiple-spring-boot-apps-docker-compose/playbookCommands.sh:
--------------------------------------------------------------------------------
1 |
2 | # Scale Spring Boot Apps on Docker Windows
3 | ansible-playbook -i hostsfile ansible-windows-docker-springboot.yml --extra-vars "host=ansible-windows-docker-springboot-dev"
4 |
5 |
--------------------------------------------------------------------------------
/step3-multiple-spring-boot-apps-docker-compose/spring-boot-app-health-check.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Defining needed variables
3 | set_fact:
4 | spring_boot_app:
5 | name: "{{ item.name }}"
6 | port: "{{ item.port }}"
7 |
8 | - name: Obtain the Docker Container´s internal IP address (because localhost doesn´t work for now https://github.com/docker/for-win/issues/458)
9 | win_shell: "docker inspect -f {% raw %}'{{ .NetworkSettings.Networks.nat.IPAddress }}' {% endraw %} springboot_{{spring_boot_app.name}}_1 {{ '>' }} container_ip.txt"
10 |
11 | - name: Get the Docker Container´s internal IP address from the temporary txt-file (we have to do this because of templating problems, see http://stackoverflow.com/a/32279729/4964553)
12 | win_shell: cat container_ip.txt
13 | register: win_shell_txt_return
14 |
15 | - name: Define the IP as variable
16 | set_fact:
17 | docker_container_ip: "{{ win_shell_txt_return.stdout.splitlines()[0] }}"
18 |
19 | - debug:
20 | msg: "The Docker Container that runs your App '{{spring_boot_app.name}}' has the internal IP {{ docker_container_ip }} --> Let´s do a health-check against this URI: 'http://{{ docker_container_ip }}:{{spring_boot_app.port}}/health'"
21 |
22 | # Spring Boot Actuators strange Content-Type 'application/vnd.spring-boot.actuator.v1+json' when calling
23 | # http://appname:port/health can be avoided by using the a correct header: 'Accept: application/json'
24 | # Doing so, the app reacts with a normal 'application/json' in the response and the healthcheck run's fine again :)
25 | - name: Wait until our Spring Boot app is up & running
26 | win_uri:
27 | url: "http://{{ docker_container_ip }}:{{spring_boot_app.port}}/health"
28 | method: GET
29 | headers:
30 | Accept: application/json
31 | register: health_result
32 | until: health_result.status_code == 200
33 | retries: 30
34 | delay: 20
35 | ignore_errors: yes
36 |
37 | - name: Show some more info, only when health check went wrong
38 | win_uri:
39 | url: "http://{{ docker_container_ip }}:{{spring_boot_app.port}}/health"
40 | method: GET
41 | register: health_bad_result
42 | ignore_errors: yes
43 | when: health_result|failed
44 |
45 | - name: Show some more info, only when health check went wrong
46 | debug:
47 | msg: "The app reacted with: {{health_bad_result}}"
48 | when: health_result|failed
49 |
50 |
--------------------------------------------------------------------------------
/step3-multiple-spring-boot-apps-docker-compose/spring-boot-app-prepare.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Defining needed variables
3 | set_fact:
4 | spring_boot_app:
5 | name: "{{ item.name }}"
6 | port: "{{ item.port }}"
7 | jar: "{{ item.path_to_jar }}"
8 | registry_name: "{{ item.service_registry_name }}"
9 |
10 | - name: Preparing the following Spring Boot App´s Files for docker-compose run
11 | debug:
12 | msg: "Processing '{{spring_boot_app.name}}' with port '{{ spring_boot_app.port }}'"
13 |
14 | - name: Create directory C:\springboot\spring_boot_app.name, if not there
15 | win_file: path={{base_path}}\\{{spring_boot_app.name}} state=directory
16 |
17 | - name: Template and copy Spring Boot app´s Dockerfile to directory C:\springboot\spring_boot_app.name
18 | win_template:
19 | src: "templates/Dockerfile-SpringBoot-App.j2"
20 | dest: "{{base_path}}\\{{spring_boot_app.name}}\\Dockerfile"
21 |
22 | - name: Copy Spring Boot app´s jar-File to directory C:\springboot\spring_boot_app.name
23 | win_copy:
24 | src: "{{spring_boot_app.jar}}"
25 | dest: "{{base_path}}\\{{spring_boot_app.name}}\\{{spring_boot_app.name}}.jar"
26 |
--------------------------------------------------------------------------------
/step3-multiple-spring-boot-apps-docker-compose/templates/Dockerfile-SpringBoot-App.j2:
--------------------------------------------------------------------------------
1 | #jinja2: newline_sequence:'\r\n'
2 | FROM springboot-oraclejre-nanoserver:latest
3 |
4 | MAINTAINER Jonas Hecht
5 |
6 | ENV REGISTRY_HOST {{spring_boot_app.registry_name}}
7 | ENV SPRINGBOOT_APP_NAME {{spring_boot_app.name}}
8 |
9 | # Expose the apps Port
10 | EXPOSE {{spring_boot_app.port}}
11 |
12 | # Add Spring Boot app.jar to Container
13 | ADD {{spring_boot_app.name}}.jar app.jar
14 |
15 | # Fire up our Spring Boot app by default
16 | CMD ["java.exe", "-jar app.jar --server.port={{spring_boot_app.port}}"]
17 |
18 |
--------------------------------------------------------------------------------
/step3-multiple-spring-boot-apps-docker-compose/templates/docker-compose.j2:
--------------------------------------------------------------------------------
1 | #jinja2: newline_sequence:'\r\n'
2 | version: '3.2'
3 |
4 | services:
5 |
6 | {% for service in vars.services %}
7 | {{ service.name }}:
8 | build: ./{{ service.name }}
9 | {% if service.map_to_same_port_on_host is defined %}
10 | ports:
11 | - "{{ service.port }}:{{ service.port }}"
12 | {% else %}
13 | ports:
14 | - "{{ service.port }}"
15 | {% endif %}
16 | tty:
17 | true
18 | restart:
19 | unless-stopped
20 | {% endfor %}
21 |
22 | networks:
23 | default:
24 | external:
25 | name: "nat"
--------------------------------------------------------------------------------
/step4-windows-linux-multimachine-vagrant-docker-swarm-setup/Vagrantfile:
--------------------------------------------------------------------------------
1 | Vagrant.configure("2") do |config|
2 |
3 | # One Master / Manager Node with Linux
4 | config.vm.define "masterlinux" do |masterlinux|
5 | masterlinux.vm.box = "ubuntu/xenial64"
6 | masterlinux.vm.hostname = "masterlinux01"
7 |
8 | # Register domain test for later routing prettiness with Traefik
9 | masterlinux.dns.tld = "test"
10 |
11 | # Forwarding the port for Ansible explicitely to not run into Vagrants 'Port Collisions and Correction'
12 | # see https://www.vagrantup.com/docs/networking/forwarded_ports.html, which would lead to problems with Ansible later
13 | masterlinux.vm.network "forwarded_port", guest: 22, host: 2222, host_ip: "127.0.0.1", id: "ssh"
14 |
15 | # As to https://www.vagrantup.com/docs/multi-machine/ & https://www.vagrantup.com/docs/networking/private_network.html
16 | # we need to configure a private network, so that our machines are able to talk to one another
17 | masterlinux.vm.network "private_network", ip: "172.16.2.10"
18 |
19 | masterlinux.vm.provider :virtualbox do |virtualbox|
20 | virtualbox.name = "MasterLinuxUbuntu"
21 | virtualbox.gui = true
22 | virtualbox.memory = 2048
23 | virtualbox.cpus = 2
24 | virtualbox.customize ["modifyvm", :id, "--ioapic", "on"]
25 | virtualbox.customize ["modifyvm", :id, "--vram", "32"]
26 | # Forward DNS resolver from host (vagrant dns) to box
27 | virtualbox.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
28 | end
29 |
30 | # Forwarding the Guest to Host ports, so that we can access it easily from outside the VM
31 | masterlinux.vm.network "forwarded_port", guest: 9000, host: 49000, host_ip: "127.0.0.1", id: "portainer"
32 | masterlinux.vm.network "forwarded_port", guest: 8080, host: 48080, host_ip: "127.0.0.1", id: "traefik_dashboard"
33 | masterlinux.vm.network "forwarded_port", guest: 80, host: 40080, host_ip: "127.0.0.1", id: "traefik"
34 |
35 | # Open App ports for access from outside the VM
36 | masterlinux.vm.network "forwarded_port", guest: 8761, host: 8761, host_ip: "127.0.0.1", id: "eureka"
37 | masterlinux.vm.network "forwarded_port", guest: 8092, host: 8092, host_ip: "127.0.0.1", id: "spring-boot-admin"
38 | masterlinux.vm.network "forwarded_port", guest: 8090, host: 8090, host_ip: "127.0.0.1", id: "weatherbackend"
39 | masterlinux.vm.network "forwarded_port", guest: 8091, host: 8091, host_ip: "127.0.0.1", id: "weatherbockend"
40 | masterlinux.vm.network "forwarded_port", guest: 8095, host: 8095, host_ip: "127.0.0.1", id: "weatherservice"
41 | end
42 |
43 | # One Worker Node with Linux
44 | config.vm.define "workerlinux" do |workerlinux|
45 | workerlinux.vm.box = "ubuntu/xenial64"
46 | workerlinux.vm.hostname = "workerlinux01"
47 |
48 | # Forwarding the port for Ansible explicitely to not run into Vagrants 'Port Collisions and Correction'
49 | # see https://www.vagrantup.com/docs/networking/forwarded_ports.html, which would lead to problems with Ansible later
50 | workerlinux.vm.network "forwarded_port", guest: 22, host: 2232, host_ip: "127.0.0.1", id: "ssh"
51 |
52 | # As to https://www.vagrantup.com/docs/multi-machine/ & https://www.vagrantup.com/docs/networking/private_network.html
53 | # we need to configure a private network, so that our machines are able to talk to one another
54 | workerlinux.vm.network "private_network", ip: "172.16.2.11"
55 |
56 | workerlinux.vm.provider :virtualbox do |virtualbox|
57 | virtualbox.name = "WorkerLinuxUbuntu"
58 | virtualbox.gui = true
59 | virtualbox.memory = 2048
60 | virtualbox.cpus = 2
61 | virtualbox.customize ["modifyvm", :id, "--ioapic", "on"]
62 | virtualbox.customize ["modifyvm", :id, "--vram", "32"]
63 | # Forward DNS resolver from host (vagrant dns) to box
64 | virtualbox.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
65 | end
66 |
67 | # Forwarding the Guest to Host ports, so that we can access it easily from outside the VM
68 | workerlinux.vm.network "forwarded_port", guest: 8080, host: 48081, host_ip: "127.0.0.1", id: "traefik_dashboard"
69 | workerlinux.vm.network "forwarded_port", guest: 80, host: 40081, host_ip: "127.0.0.1", id: "traefik"
70 | end
71 |
72 | # One Master / Manager Node with Windows Server 2016
73 | config.vm.define "masterwindows1803" do |masterwindows|
74 | masterwindows.vm.box = "windows_1803_docker_multimachine"
75 | masterwindows.vm.hostname = "masterwindows01"
76 |
77 | # Forwarding the port for Ansible explicitely to not run into Vagrants 'Port Collisions and Correction'
78 | # see https://www.vagrantup.com/docs/networking/forwarded_ports.html, which would lead to problems with Ansible later
79 | masterwindows.vm.network "forwarded_port", guest: 5986, host: 55986, host_ip: "127.0.0.1", id: "winrm-ssl"
80 |
81 | # As to https://www.vagrantup.com/docs/multi-machine/ & https://www.vagrantup.com/docs/networking/private_network.html
82 | # we need to configure a private network, so that our machines are able to talk to one another
83 | masterwindows.vm.network "private_network", ip: "172.16.2.12"
84 |
85 | masterwindows.vm.provider :virtualbox do |virtualbox|
86 | virtualbox.name = "MasterWindowsServer1803"
87 | virtualbox.gui = true
88 | virtualbox.memory = 2048
89 | virtualbox.cpus = 2
90 | # Forward DNS resolver from host (vagrant dns) to box
91 | virtualbox.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
92 | end
93 | # Forwarding the Guest to Host ports, so that we can access it easily from outside the VM
94 | masterwindows.vm.network "forwarded_port", guest: 8080, host: 48082, host_ip: "127.0.0.1", id: "traefik_dashboard"
95 | masterwindows.vm.network "forwarded_port", guest: 80, host: 40082, host_ip: "127.0.0.1", id: "traefik"
96 |
97 | # Open App ports for access from outside the VM
98 | masterwindows.vm.network "forwarded_port", guest: 8761, host: 48761, host_ip: "127.0.0.1", id: "eureka"
99 | masterwindows.vm.network "forwarded_port", guest: 8090, host: 48090, host_ip: "127.0.0.1", id: "weatherbackend"
100 | masterwindows.vm.network "forwarded_port", guest: 8091, host: 48091, host_ip: "127.0.0.1", id: "weatherbockend"
101 | masterwindows.vm.network "forwarded_port", guest: 8095, host: 48095, host_ip: "127.0.0.1", id: "weatherservice"
102 | end
103 |
104 | # One Worker Node with Windows Server 2016
105 | config.vm.define "workerwindows1803" do |workerwindows|
106 | workerwindows.vm.box = "windows_1803_docker_multimachine"
107 | workerwindows.vm.hostname = "workerwindows01"
108 |
109 | # Forwarding the port for Ansible explicitely to not run into Vagrants 'Port Collisions and Correction'
110 | # see https://www.vagrantup.com/docs/networking/forwarded_ports.html, which would lead to problems with Ansible later
111 | workerwindows.vm.network "forwarded_port", guest: 5986, host: 55996, host_ip: "127.0.0.1", id: "winrm-ssl"
112 |
113 | # As to https://www.vagrantup.com/docs/multi-machine/ & https://www.vagrantup.com/docs/networking/private_network.html
114 | # we need to configure a private network, so that our machines are able to talk to one another
115 | workerwindows.vm.network "private_network", ip: "172.16.2.13"
116 |
117 | workerwindows.vm.provider :virtualbox do |virtualbox|
118 | virtualbox.name = "WorkerWindowsServer1803"
119 | virtualbox.gui = true
120 | virtualbox.memory = 2048
121 | virtualbox.cpus = 2
122 | # Forward DNS resolver from host (vagrant dns) to box
123 | virtualbox.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
124 | end
125 |
126 | # Forwarding the Guest to Host ports, so that we can access it easily from outside the VM
127 | workerwindows.vm.network "forwarded_port", guest: 8080, host: 48083, host_ip: "127.0.0.1", id: "traefik_dashboard"
128 | workerwindows.vm.network "forwarded_port", guest: 80, host: 40083, host_ip: "127.0.0.1", id: "traefik"
129 | end
130 |
131 | end
--------------------------------------------------------------------------------
/step4-windows-linux-multimachine-vagrant-docker-swarm-setup/allow-http-docker-registry.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - hosts: all
3 |
4 | tasks:
5 | - name: Template daemon.json to /etc/docker/daemon.json on Linux nodes for later Registry access
6 | template:
7 | src: "templates/daemon.j2"
8 | dest: "/etc/docker/daemon.json"
9 | become: yes
10 | when: inventory_hostname in groups['linux']
11 |
12 | - name: Template daemon.json to C:\ProgramData\docker\config\daemon.json on Windows nodes for later Registry access
13 | win_template:
14 | src: "templates/daemon.j2"
15 | dest: "C:\\ProgramData\\docker\\config\\daemon.json"
16 | when: inventory_hostname in groups['windows']
17 |
18 | - name: Restart Docker service on Linux nodes, so that Registry access configuration is available
19 | service:
20 | name: docker
21 | state: restarted
22 | become: yes
23 | when: inventory_hostname in groups['linux']
24 |
25 | - name: Restart Docker service on Windows nodes, so that Registry access configuration is available
26 | win_service:
27 | name: docker
28 | state: restarted
29 | when: inventory_hostname in groups['windows']
30 |
--------------------------------------------------------------------------------
/step4-windows-linux-multimachine-vagrant-docker-swarm-setup/display-swarm-status.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Obtain Docker Swarm status
3 | win_shell: "docker node ls"
4 | register: overview_result
5 | ignore_errors: yes
6 | when: inventory_hostname == "masterwindows01"
7 |
8 | - name: Swarm initialized...
9 | debug:
10 | msg:
11 | - "The status of the Swarm now is:"
12 | - "{{overview_result.stdout_lines}}"
13 | when: inventory_hostname == "masterwindows01"
14 |
15 | - name: Obtain currently running Docker Swarm services
16 | win_shell: "docker service ls"
17 | register: services_result
18 | ignore_errors: yes
19 | when: inventory_hostname == "masterwindows01"
20 |
21 | - name: Swarm initialized...
22 | debug:
23 | msg:
24 | - "The following Docker Swarm services are currently running (you may also check out Portainer Swarm visualizer at http://localhost:49000/ on your Vagrant host):"
25 | - "{{services_result.stdout_lines}}"
26 | when: inventory_hostname == "masterwindows01"
--------------------------------------------------------------------------------
/step4-windows-linux-multimachine-vagrant-docker-swarm-setup/group_vars/all.yml:
--------------------------------------------------------------------------------
1 | ansible_user: vagrant
2 |
--------------------------------------------------------------------------------
/step4-windows-linux-multimachine-vagrant-docker-swarm-setup/group_vars/linux.yml:
--------------------------------------------------------------------------------
1 | ansible_connection: ssh
2 |
3 | # Ubuntu 16.04 comes without Python 2, so one gets errors like "Shared connection to 127.0.0.1 closed.\r\n", "module_stdout": "/bin/sh: 1: /usr/bin/python: not found\r\n",
4 | # as Python 3 is already there, we´re switching over to it (see http://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html#list-of-behavioral-inventory-parameters)
5 | ansible_python_interpreter: /usr/bin/python3
6 |
--------------------------------------------------------------------------------
/step4-windows-linux-multimachine-vagrant-docker-swarm-setup/group_vars/masterlinux.yml:
--------------------------------------------------------------------------------
1 | ansible_port: 2222
2 |
3 | # By default (config.ssh.insert_key is defaulting to true, even if unset) Vagrant generates a new Keypair and places the private key
4 | # inside .vagrant/machines/default/virtualbox/private_key & automatically copies the public key to /home/vagrant/.ssh/authorized_keys
5 | # the path should remain stable, but if it changes, just check with `vagrant ssh-config` on commandline
6 | ansible_ssh_private_key_file: .vagrant/machines/masterlinux/virtualbox/private_key
--------------------------------------------------------------------------------
/step4-windows-linux-multimachine-vagrant-docker-swarm-setup/group_vars/masterwindows.yml:
--------------------------------------------------------------------------------
1 | ansible_port: 55986
--------------------------------------------------------------------------------
/step4-windows-linux-multimachine-vagrant-docker-swarm-setup/group_vars/windows.yml:
--------------------------------------------------------------------------------
1 | ansible_password: vagrant
2 |
3 | # http://docs.ansible.com/ansible/intro_windows.html#windows-how-does-it-work
4 | ansible_connection: winrm
5 |
6 | # The following is necessary for Python 2.7.9+ when using default WinRM self-signed certificates:
7 | ansible_winrm_server_cert_validation: ignore
8 |
9 | # to avoid time out errors like 'Read timed out. (read timeout=30)', we raise the timeout generally
10 | # see https://github.com/ansible/ansible-modules-core/issues/5368
11 | ansible_winrm_read_timeout_sec: 40
--------------------------------------------------------------------------------
/step4-windows-linux-multimachine-vagrant-docker-swarm-setup/group_vars/workerlinux.yml:
--------------------------------------------------------------------------------
1 | ansible_port: 2232
2 |
3 | # By default (config.ssh.insert_key is defaulting to true, even if unset) Vagrant generates a new Keypair and places the private key
4 | # inside .vagrant/machines/default/virtualbox/private_key & automatically copies the public key to /home/vagrant/.ssh/authorized_keys
5 | # the path should remain stable, but if it changes, just check with `vagrant ssh-config` on commandline
6 | ansible_ssh_private_key_file: .vagrant/machines/workerlinux/virtualbox/private_key
--------------------------------------------------------------------------------
/step4-windows-linux-multimachine-vagrant-docker-swarm-setup/group_vars/workerwindows.yml:
--------------------------------------------------------------------------------
1 | ansible_port: 55996
--------------------------------------------------------------------------------
/step4-windows-linux-multimachine-vagrant-docker-swarm-setup/hostsfile:
--------------------------------------------------------------------------------
1 | [masterwindows]
2 | masterwindows01
3 |
4 | [masterlinux]
5 | masterlinux01
6 |
7 | [workerwindows]
8 | workerwindows01
9 |
10 | [workerlinux]
11 | workerlinux01
12 |
13 | [linux:children]
14 | masterlinux
15 | workerlinux
16 |
17 | [windows:children]
18 | masterwindows
19 | workerwindows
--------------------------------------------------------------------------------
/step4-windows-linux-multimachine-vagrant-docker-swarm-setup/initialize-docker-swarm.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - hosts: all
3 | vars:
4 | masterwindows_ip: 172.16.2.12
5 |
6 | tasks:
7 | - name: Checking Ansible connectivity to Windows nodes
8 | win_ping:
9 | when: inventory_hostname in groups['windows']
10 |
11 | - name: Checking Ansible connectivity to Linux nodes
12 | ping:
13 | when: inventory_hostname in groups['linux']
14 |
15 | - name: Open Ports in firewalls needed for Docker Swarm
16 | include_tasks: prepare-firewalls-for-swarm.yml
17 |
18 | - name: Initialize Swarm and join all Swarm nodes
19 | include_tasks: initialize-swarm-and-join-all-nodes.yml
20 |
21 | - name: Label underlying operation system to each node
22 | include_tasks: label-os-specific-nodes.yml
23 |
24 | - name: Run Portainer as Docker and Docker Swarm Visualizer
25 | include_tasks: run-portainer.yml
26 |
27 | - name: Run Docker Swarm local Registry
28 | include_tasks: run-swarm-registry.yml
29 |
30 | - name: Display the current Docker Swarm status
31 | include_tasks: display-swarm-status.yml
--------------------------------------------------------------------------------
/step4-windows-linux-multimachine-vagrant-docker-swarm-setup/initialize-swarm-and-join-all-nodes.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Leave Swarm on Windows master node, if there was a cluster before
3 | win_shell: "docker swarm leave --force"
4 | ignore_errors: yes
5 | when: inventory_hostname == "masterwindows01"
6 |
7 | - name: Initialize Docker Swarm cluster on Windows master node
8 | win_shell: "docker swarm init --advertise-addr={{masterwindows_ip}} --listen-addr {{masterwindows_ip}}:2377"
9 | ignore_errors: yes
10 | when: inventory_hostname == "masterwindows01"
11 |
12 | - name: Pause a few seconds after new Swarm cluster initialization to prevent later errors on obtaining tokens to early
13 | pause:
14 | seconds: 5
15 |
16 | - name: Obtain worker join-token from Windows master node
17 | win_shell: "docker swarm join-token worker -q"
18 | register: worker_token_result
19 | ignore_errors: yes
20 | when: inventory_hostname == "masterwindows01"
21 |
22 | - name: Obtain manager join-token from Windows master node
23 | win_shell: "docker swarm join-token manager -q"
24 | register: manager_token_result
25 | ignore_errors: yes
26 | when: inventory_hostname == "masterwindows01"
27 |
28 | - name: Syncing the worker and manager join-token results to the other hosts
29 | set_fact:
30 | worker_token_result_host_sync: "{{ hostvars['masterwindows01']['worker_token_result'] }}"
31 | manager_token_result_host_sync: "{{ hostvars['masterwindows01']['manager_token_result'] }}"
32 |
33 | - name: Extracting and saving worker and manager join-tokens in variables for joining other nodes later
34 | set_fact:
35 | worker_jointoken: "{{worker_token_result_host_sync.stdout.splitlines()[0]}}"
36 | manager_jointoken: "{{manager_token_result_host_sync.stdout.splitlines()[0]}}"
37 |
38 | - name: Join-tokens...
39 | debug:
40 | msg:
41 | - "The worker join-token is: '{{worker_jointoken}}'"
42 | - "The manager join-token is: '{{manager_jointoken}}'"
43 |
44 | - name: Leave Swarm on Windows worker nodes, if there was a cluster before
45 | win_shell: "docker swarm leave"
46 | ignore_errors: yes
47 | when: inventory_hostname in groups['workerwindows']
48 |
49 | - name: Add Windows worker nodes to Docker Swarm cluster
50 | win_shell: "docker swarm join --token {{worker_jointoken}} {{masterwindows_ip}}"
51 | ignore_errors: yes
52 | when: inventory_hostname in groups['workerwindows']
53 |
54 | - name: Leave Swarm on Linux worker nodes, if there was a cluster before
55 | shell: "docker swarm leave"
56 | ignore_errors: yes
57 | when: inventory_hostname in groups['workerlinux']
58 |
59 | - name: Add Linux worker nodes to Docker Swarm cluster
60 | shell: "docker swarm join --token {{worker_jointoken}} {{masterwindows_ip}}"
61 | ignore_errors: yes
62 | when: inventory_hostname in groups['workerlinux']
63 |
64 | - name: Leave Swarm on Linux manager nodes, if there was a cluster before
65 | shell: "docker swarm leave --force"
66 | ignore_errors: yes
67 | when: inventory_hostname in groups['masterlinux']
68 |
69 | - name: Add Linux manager nodes to Docker Swarm cluster
70 | shell: "docker swarm join --token {{manager_jointoken}} {{masterwindows_ip}}"
71 | ignore_errors: yes
72 | when: inventory_hostname in groups['masterlinux']
73 |
--------------------------------------------------------------------------------
/step4-windows-linux-multimachine-vagrant-docker-swarm-setup/label-os-specific-nodes.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Label OS specific nodes for later mixed-OS deployments (masterwindows01 = windows)
3 | win_shell: "docker node update --label-add os=windows masterwindows01"
4 | ignore_errors: yes
5 | when: inventory_hostname == "masterwindows01"
6 |
7 | - name: Label OS specific nodes for later mixed-OS deployments (workerwindows01 = windows)
8 | win_shell: "docker node update --label-add os=windows workerwindows01"
9 | ignore_errors: yes
10 | when: inventory_hostname == "masterwindows01"
11 |
12 | - name: Label OS specific nodes for later mixed-OS deployments (workerlinux01 = linux)
13 | win_shell: "docker node update --label-add os=linux workerlinux01"
14 | ignore_errors: yes
15 | when: inventory_hostname == "masterwindows01"
16 |
17 | - name: Label OS specific nodes for later mixed-OS deployments (masterlinux01 = linux)
18 | win_shell: "docker node update --label-add os=linux masterlinux01"
19 | ignore_errors: yes
20 | when: inventory_hostname == "masterwindows01"
21 |
--------------------------------------------------------------------------------
/step4-windows-linux-multimachine-vagrant-docker-swarm-setup/playbookCommands.sh:
--------------------------------------------------------------------------------
1 | # Prepare Docker on all Cluster nodes
2 | ansible-playbook -i hostsfile prepare-docker-nodes.yml
3 |
4 | # Only prepare base image springboot-oraclejre-nanoserver
5 | ansible-playbook -i hostsfile prepare-docker-nodes.yml --tags "baseimage"
6 |
7 | # Leave out newer Docker installation
8 | ansible-playbook -i hostsfile prepare-docker-nodes.yml --skip-tags "dockerinstall"
9 |
10 | # Initialize Docker Swarm
11 | ansible-playbook -i hostsfile initialize-docker-swarm.yml
12 |
13 |
--------------------------------------------------------------------------------
/step4-windows-linux-multimachine-vagrant-docker-swarm-setup/prepare-docker-linux.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - hosts: "{{host}}"
3 | become: true
4 | gather_facts: true
5 |
6 | pre_tasks:
7 | - name: update apt and autoremove
8 | apt:
9 | update_cache: yes
10 | cache_valid_time: 3600
11 | autoremove: yes
12 |
13 | tasks:
14 | - name: Add Docker apt key
15 | apt_key:
16 | url: https://download.docker.com/linux/ubuntu/gpg
17 | id: 9DC858229FC7DD38854AE2D88D81803C0EBFCD88
18 | state: present
19 | register: add_repository_key
20 | ignore_errors: true
21 |
22 | - name: Add docker apt repo
23 | apt_repository:
24 | repo: "deb [arch=amd64] https://download.docker.com/linux/ubuntu {{ansible_lsb.codename}} edge"
25 | update_cache: yes
26 | become: true
27 |
28 | - name: Install Docker apt package
29 | apt:
30 | pkg: docker-ce
31 | state: latest
32 | update_cache: yes
33 | become: true
34 |
35 | - name: Ensure Docker service is installed and restarted
36 | service:
37 | name: docker
38 | state: restarted
39 | enabled: yes
40 |
41 | - name: Install pip
42 | apt:
43 | name: python3-pip
44 | state: latest
45 |
46 | - name: Install Docker Compose
47 | pip:
48 | name: docker-compose
49 |
50 | - name: Add vagrant user to docker group.
51 | user:
52 | name: vagrant
53 | groups: docker
54 | append: yes
55 | become: true
--------------------------------------------------------------------------------
/step4-windows-linux-multimachine-vagrant-docker-swarm-setup/prepare-docker-nodes.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - hosts: all
3 |
4 | tasks:
5 | - name: Checking Ansible connectivity to Windows nodes
6 | win_ping:
7 | when: inventory_hostname in groups['windows']
8 |
9 | - name: Checking Ansible connectivity to Linux nodes
10 | ping:
11 | when: inventory_hostname in groups['linux']
12 |
13 | - name: Prepare Docker on Windows nodes
14 | import_playbook: "../step1-prepare-docker-windows/prepare-docker-windows.yml host=windows"
15 |
16 | - name: Prepare Docker on Linux nodes
17 | import_playbook: prepare-docker-linux.yml host=linux
18 |
19 | - name: Allow local http Docker registry
20 | import_playbook: allow-http-docker-registry.yml
21 |
--------------------------------------------------------------------------------
/step4-windows-linux-multimachine-vagrant-docker-swarm-setup/prepare-firewalls-for-swarm.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Allow Ping requests on Windows nodes (which is by default disabled in Windows Server 2016)
3 | win_firewall_rule:
4 | name: Allow incoming ping requests
5 | action: allow
6 | direction: in
7 | protocol: "icmpv4:8"
8 | state: present
9 | enabled: yes
10 | when: inventory_hostname in groups['windows']
11 |
12 | - name: Allow connection to TCP port 2377 for cluster management communications
13 | win_firewall_rule:
14 | name: Port 2377
15 | localport: 2377
16 | action: allow
17 | direction: in
18 | protocol: tcp
19 | state: present
20 | enabled: yes
21 | when: inventory_hostname in groups['masterwindows']
22 |
23 | # Container networking needs more open ports later, see https://docs.docker.com/engine/swarm/ingress/
24 | - name: Open ports for later Docker Swarm Container network discovery on TCP and UDP port 7946
25 | win_firewall_rule:
26 | name: Port 7946
27 | localport: 7946
28 | action: allow
29 | direction: in
30 | protocol: tcp
31 | state: present
32 | enabled: yes
33 | when: inventory_hostname in groups['windows']
34 |
35 | - name: Open ports for later Docker Swarm Container network discovery on UDP port 4789
36 | win_firewall_rule:
37 | name: Port 4789
38 | localport: 4789
39 | action: allow
40 | direction: in
41 | protocol: udp
42 | state: present
43 | enabled: yes
44 | when: inventory_hostname in groups['windows']
45 |
46 | # temporarily disabling the complete firewall to prevent issues
47 | - name: Disable firewall for Domain, Public and Private profiles
48 | win_firewall:
49 | state: disabled
50 | profiles:
51 | - Domain
52 | - Private
53 | - Public
54 | when: inventory_hostname in groups['windows']
55 | tags: disable_firewall
--------------------------------------------------------------------------------
/step4-windows-linux-multimachine-vagrant-docker-swarm-setup/run-portainer.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Create directory for later volume mount into Portainer service on Linux Manager node, if it doesn´t exist
3 | file:
4 | path: /mnt/portainer
5 | state: directory
6 | mode: 0755
7 | when: inventory_hostname in groups['linux']
8 | become: true
9 |
10 | - name: Run Portainer Docker and Docker Swarm Visualizer on Linux Manager node as Swarm service
11 | shell: "docker service create --detach --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:latest -H unix:///var/run/docker.sock"
12 | ignore_errors: yes
13 | when: inventory_hostname == "masterlinux01"
14 |
--------------------------------------------------------------------------------
/step4-windows-linux-multimachine-vagrant-docker-swarm-setup/run-swarm-registry.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Specify to run Docker Registry on Linux Manager node
3 | shell: "docker node update --label-add registry=true masterlinux01"
4 | ignore_errors: yes
5 | when: inventory_hostname == "masterlinux01"
6 |
7 | - name: Create directory for later volume mount into the Docker Registry service on Linux Manager node, if it doesn´t exist
8 | file:
9 | path: /mnt/registry
10 | state: directory
11 | mode: 0755
12 | when: inventory_hostname in groups['linux']
13 | become: true
14 |
15 | - name: Run Docker Registry on Linux Manager node as Swarm service
16 | shell: "docker service create --detach --name swarm-registry --constraint 'node.labels.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"
17 | ignore_errors: yes
18 | when: inventory_hostname == "masterlinux01"
19 |
--------------------------------------------------------------------------------
/step4-windows-linux-multimachine-vagrant-docker-swarm-setup/templates/daemon.j2:
--------------------------------------------------------------------------------
1 | {
2 | "insecure-registries" : ["172.16.2.10:5000"]
3 | }
--------------------------------------------------------------------------------
/step5-deploy-multiple-spring-boot-apps-to-mixed-os-docker-swarm/build-and-deploy-apps-2-swarm.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - hosts: all
3 | vars:
4 | application_stack_name: clearsky
5 | registry_host: 172.16.2.10:5000
6 | swarm_network_name: mixed_swarm_net
7 | docker_domain: masterlinux01.test
8 | base_path_windows: "C:\\springboot"
9 | base_path_linux: "/tmp/springboot"
10 | services:
11 |
12 | - name: eureka-serviceregistry
13 | path_to_jar: "../../cxf-spring-cloud-netflix-docker/eureka-serviceregistry/target/eureka-serviceregistry-0.0.1-SNAPSHOT.jar"
14 | port: 8761
15 | service_registry_name: eureka-serviceregistry
16 | deploy_target: linux
17 | replicas: 1
18 |
19 | - name: spring-boot-admin
20 | path_to_jar: "../../cxf-spring-cloud-netflix-docker/spring-boot-admin/target/spring-boot-admin-0.0.1-SNAPSHOT.jar"
21 | port: 8092
22 | service_registry_name: eureka-serviceregistry
23 | deploy_target: windows
24 | replicas: 1
25 |
26 | - name: weatherbackend
27 | path_to_jar: "../../cxf-spring-cloud-netflix-docker/weatherbackend/target/weatherbackend-0.0.1-SNAPSHOT.jar"
28 | port: 8090
29 | service_registry_name: eureka-serviceregistry
30 | deploy_target: linux
31 | replicas: 2
32 |
33 | - name: weatherbockend
34 | path_to_jar: "../../cxf-spring-cloud-netflix-docker/weatherbackend/target/weatherbackend-0.0.1-SNAPSHOT.jar"
35 | port: 8091
36 | service_registry_name: eureka-serviceregistry
37 | deploy_target: windows
38 | replicas: 2
39 |
40 | - name: weatherservice
41 | path_to_jar: "../../cxf-spring-cloud-netflix-docker/weatherservice/target/weatherservice-0.0.1-SNAPSHOT.jar"
42 | port: 8095
43 | service_registry_name: eureka-serviceregistry
44 | deploy_target: windows
45 | replicas: 2
46 |
47 | tasks:
48 |
49 | - name: Create Docker build directory /tmp/springboot on Linux manager node, if not there
50 | file:
51 | path: "{{base_path_linux}}"
52 | state: directory
53 | mode: 0755
54 | when: inventory_hostname == "masterlinux01"
55 | tags: buildapps
56 |
57 | - name: Create Docker build directory C:\springboot on Windows manager node, if not there
58 | win_file:
59 | path: "{{base_path_windows}}"
60 | state: directory
61 | when: inventory_hostname == "masterwindows01"
62 | tags: buildapps
63 |
64 | - name: Build Linux Apps Docker images on Linux manager node and push to Docker Swarm registry
65 | include_tasks: prepare-docker-images-linux.yml
66 | with_items: "{{ vars.services }}"
67 | when: inventory_hostname == "masterlinux01" and item.deploy_target == 'linux'
68 | tags: buildapps
69 |
70 | - name: Build Windows Apps Docker images on Windows manager node and push to Docker Swarm registry
71 | include_tasks: prepare-docker-images-windows.yml
72 | with_items: "{{ vars.services }}"
73 | when: inventory_hostname == "masterwindows01" and item.deploy_target == 'windows'
74 | tags: buildapps
75 |
76 | - name: Open all published ports of every app on every node for later access from outside the Swarm
77 | include_tasks: prepare-firewall-app-access.yml
78 | with_items: "{{ vars.services }}"
79 | tags: firewall
80 |
81 | - name: Deploy the Stack to the Swarm on Windows Manager node
82 | include_tasks: deploy-services-swarm.yml
83 | when: inventory_hostname == "masterwindows01"
84 | tags: deploy
85 |
86 | - name: Display the current Docker Swarm status
87 | include_tasks: ../step4-windows-linux-multimachine-vagrant-docker-swarm-setup/display-swarm-status.yml
88 |
89 | # - name: Do healthchecks for all services
90 | # include_tasks: spring-boot-app-health-check.yml
91 | # with_items: "{{ vars.services }}"
--------------------------------------------------------------------------------
/step5-deploy-multiple-spring-boot-apps-to-mixed-os-docker-swarm/deploy-services-swarm.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Template docker-stack.yml to directory C:\spring-boot
3 | win_template:
4 | src: "templates/docker-stack.j2"
5 | dest: "{{base_path_windows}}\\docker-stack.yml"
6 |
7 | - name: Remove old Stack from the Swarm, if there
8 | win_shell: docker stack rm {{ application_stack_name }}
9 | args:
10 | chdir: "{{base_path_windows}}"
11 | ignore_errors: yes
12 |
13 | - name: Delete old Swarm overlay network
14 | win_shell: "docker network rm {{swarm_network_name}}"
15 | ignore_errors: yes
16 |
17 | - name: Pause a few seconds after old Stack removement
18 | pause:
19 | seconds: 2
20 |
21 | - name: Create an overlay network to enable our Swarm services to connect to each other later on
22 | win_shell: "docker network create --driver=overlay {{swarm_network_name}}"
23 | ignore_errors: yes
24 |
25 | - name: Give the Swarm a few seconds to add all peers to the new network
26 | pause:
27 | seconds: 4
28 |
29 | - name: Deploy the Stack to the Swarm on Windows Manager node
30 | win_shell: docker stack deploy --compose-file docker-stack.yml {{ application_stack_name }}
31 | args:
32 | chdir: "{{base_path_windows}}"
33 | ignore_errors: yes
34 |
--------------------------------------------------------------------------------
/step5-deploy-multiple-spring-boot-apps-to-mixed-os-docker-swarm/group_vars/all.yml:
--------------------------------------------------------------------------------
1 | ansible_user: vagrant
2 |
--------------------------------------------------------------------------------
/step5-deploy-multiple-spring-boot-apps-to-mixed-os-docker-swarm/group_vars/linux.yml:
--------------------------------------------------------------------------------
1 | ansible_connection: ssh
2 |
3 | # Ubuntu 16.04 comes without Python 2, so one gets errors like "Shared connection to 127.0.0.1 closed.\r\n", "module_stdout": "/bin/sh: 1: /usr/bin/python: not found\r\n",
4 | # as Python 3 is already there, we´re switching over to it (see http://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html#list-of-behavioral-inventory-parameters)
5 | ansible_python_interpreter: /usr/bin/python3
6 |
--------------------------------------------------------------------------------
/step5-deploy-multiple-spring-boot-apps-to-mixed-os-docker-swarm/group_vars/masterlinux.yml:
--------------------------------------------------------------------------------
1 | ansible_port: 2222
2 |
3 | # By default (config.ssh.insert_key is defaulting to true, even if unset) Vagrant generates a new Keypair and places the private key
4 | # inside .vagrant/machines/default/virtualbox/private_key & automatically copies the public key to /home/vagrant/.ssh/authorized_keys
5 | # the path should remain stable, but if it changes, just check with `vagrant ssh-config` on commandline
6 | ansible_ssh_private_key_file: ../step4-windows-linux-multimachine-vagrant-docker-swarm-setup/.vagrant/machines/masterlinux/virtualbox/private_key
--------------------------------------------------------------------------------
/step5-deploy-multiple-spring-boot-apps-to-mixed-os-docker-swarm/group_vars/masterwindows.yml:
--------------------------------------------------------------------------------
1 | ansible_port: 55986
--------------------------------------------------------------------------------
/step5-deploy-multiple-spring-boot-apps-to-mixed-os-docker-swarm/group_vars/windows.yml:
--------------------------------------------------------------------------------
1 | ansible_password: vagrant
2 |
3 | # http://docs.ansible.com/ansible/intro_windows.html#windows-how-does-it-work
4 | ansible_connection: winrm
5 |
6 | # The following is necessary for Python 2.7.9+ when using default WinRM self-signed certificates:
7 | ansible_winrm_server_cert_validation: ignore
8 |
9 | # to avoid time out errors like 'Read timed out. (read timeout=30)', we raise the timeout generally
10 | # see https://github.com/ansible/ansible-modules-core/issues/5368
11 | ansible_winrm_read_timeout_sec: 40
--------------------------------------------------------------------------------
/step5-deploy-multiple-spring-boot-apps-to-mixed-os-docker-swarm/group_vars/workerlinux.yml:
--------------------------------------------------------------------------------
1 | ansible_port: 2232
2 |
3 | # By default (config.ssh.insert_key is defaulting to true, even if unset) Vagrant generates a new Keypair and places the private key
4 | # inside .vagrant/machines/default/virtualbox/private_key & automatically copies the public key to /home/vagrant/.ssh/authorized_keys
5 | # the path should remain stable, but if it changes, just check with `vagrant ssh-config` on commandline
6 | ansible_ssh_private_key_file: ../step4-windows-linux-multimachine-vagrant-docker-swarm-setup/.vagrant/machines/workerlinux/virtualbox/private_key
--------------------------------------------------------------------------------
/step5-deploy-multiple-spring-boot-apps-to-mixed-os-docker-swarm/group_vars/workerwindows.yml:
--------------------------------------------------------------------------------
1 | ansible_port: 55996
--------------------------------------------------------------------------------
/step5-deploy-multiple-spring-boot-apps-to-mixed-os-docker-swarm/hostsfile:
--------------------------------------------------------------------------------
1 | [masterwindows]
2 | masterwindows01
3 |
4 | [masterlinux]
5 | masterlinux01
6 |
7 | [workerwindows]
8 | workerwindows01
9 |
10 | [workerlinux]
11 | workerlinux01
12 |
13 | [linux:children]
14 | masterlinux
15 | workerlinux
16 |
17 | [windows:children]
18 | masterwindows
19 | workerwindows
--------------------------------------------------------------------------------
/step5-deploy-multiple-spring-boot-apps-to-mixed-os-docker-swarm/playbookCommands.sh:
--------------------------------------------------------------------------------
1 | # Build all Applications docker images and deploy to Swarm
2 | ansible-playbook -i hostsfile build-and-deploy-apps-2-swarm.yml
3 |
4 | # Just deploy all Applications to Swarm (they have to been build once before that will work out)
5 | ansible-playbook -i hostsfile build-and-deploy-apps-2-swarm.yml --skip-tags "buildapps"
6 |
7 | # Only open Firewall ports for Apps
8 | ansible-playbook -i hostsfile build-and-deploy-apps-2-swarm.yml --skip-tags="deploy,buildapps"
9 |
10 |
--------------------------------------------------------------------------------
/step5-deploy-multiple-spring-boot-apps-to-mixed-os-docker-swarm/prepare-docker-images-linux.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Defining needed variables
3 | set_fact:
4 | spring_boot_app:
5 | name: "{{ item.name }}"
6 | port: "{{ item.port }}"
7 | jar: "{{ item.path_to_jar }}"
8 | registry_name: "{{ item.service_registry_name }}"
9 |
10 | - name: Preparing the following Spring Boot App´s Docker build files
11 | debug:
12 | msg: "Processing '{{spring_boot_app.name}}' with port '{{ spring_boot_app.port }}' on {{ item.deploy_target }}"
13 |
14 | - name: Create directory /tmp/springboot/spring_boot_app.name, if not there
15 | file:
16 | path: "{{base_path_linux}}/{{spring_boot_app.name}}"
17 | state: directory
18 | mode: 0755
19 |
20 | - name: Template and copy Spring Boot app´s Dockerfile to directory /tmp/springboot/spring_boot_app.name
21 | template:
22 | src: "templates/Dockerfile-SpringBoot-Linux.j2"
23 | dest: "{{base_path_linux}}/{{spring_boot_app.name}}/Dockerfile"
24 |
25 | - name: Copy Spring Boot app´s jar-File to directory /tmp/springboot/spring_boot_app.name
26 | copy:
27 | src: "{{spring_boot_app.jar}}"
28 | dest: "{{base_path_linux}}/{{spring_boot_app.name}}/{{spring_boot_app.name}}.jar"
29 |
30 | - name: Remove existing App´s Docker Container image
31 | shell: "docker rmi {{registry_host}}/{{spring_boot_app.name}}:latest --force"
32 | ignore_errors: yes
33 |
34 | - name: Build the Service´ Docker image
35 | shell: "docker build . --tag {{registry_host}}/{{spring_boot_app.name}}:latest"
36 | args:
37 | chdir: "{{base_path_linux}}/{{spring_boot_app.name}}"
38 |
39 | - name: Push the Docker Container image to the Swarm Registry
40 | shell: "docker push {{registry_host}}/{{spring_boot_app.name}}:latest"
41 |
42 |
--------------------------------------------------------------------------------
/step5-deploy-multiple-spring-boot-apps-to-mixed-os-docker-swarm/prepare-docker-images-windows.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Defining needed variables
3 | set_fact:
4 | spring_boot_app:
5 | name: "{{ item.name }}"
6 | port: "{{ item.port }}"
7 | jar: "{{ item.path_to_jar }}"
8 | registry_name: "{{ item.service_registry_name }}"
9 |
10 | - name: Preparing the following Spring Boot App´s Docker build files
11 | debug:
12 | msg: "Processing '{{spring_boot_app.name}}' with port '{{ spring_boot_app.port }}' on {{ item.deploy_target }}"
13 |
14 | - name: Create directory C:\springboot\spring_boot_app.name, if not there
15 | win_file:
16 | path: "{{base_path_windows}}\\{{spring_boot_app.name}}"
17 | state: directory
18 |
19 | - name: Template and copy Spring Boot app´s Dockerfile to directory C:\springboot\spring_boot_app.name
20 | win_template:
21 | src: "templates/Dockerfile-SpringBoot-Windows.j2"
22 | dest: "{{base_path_windows}}\\{{spring_boot_app.name}}\\Dockerfile"
23 |
24 | - name: Copy Spring Boot app´s jar-File to directory C:\springboot\spring_boot_app.name
25 | win_copy:
26 | src: "{{spring_boot_app.jar}}"
27 | dest: "{{base_path_windows}}\\{{spring_boot_app.name}}\\{{spring_boot_app.name}}.jar"
28 |
29 | - name: Remove existing App´s Docker Container image
30 | win_shell: "docker rmi {{registry_host}}/{{spring_boot_app.name}}:latest --force"
31 | ignore_errors: yes
32 |
33 | - name: Build the App´s Docker Container image
34 | win_shell: "docker build . --tag {{registry_host}}/{{spring_boot_app.name}}:latest"
35 | args:
36 | chdir: "{{base_path_windows}}\\{{spring_boot_app.name}}"
37 |
38 | - name: Push the Docker Container image to the Swarm Registry
39 | win_shell: "docker push {{registry_host}}/{{spring_boot_app.name}}:latest"
40 |
--------------------------------------------------------------------------------
/step5-deploy-multiple-spring-boot-apps-to-mixed-os-docker-swarm/prepare-firewall-app-access.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Preparing to open...
3 | debug:
4 | msg: "'{{ item.name }}' with port '{{ item.port }}'"
5 |
6 | - name: Open the apps published port on Linux node for later access from outside the Swarm
7 | ufw:
8 | rule: allow
9 | port: "{{ item.port }}"
10 | proto: tcp
11 | comment: "{{ item.name }}s port {{ item.port }}"
12 | become: true
13 | when: inventory_hostname in groups['linux']
14 |
15 | - name: Open the apps published port on Windows node for later access from outside the Swarm
16 | win_firewall_rule:
17 | name: "{{ item.name }}'s port {{ item.port }}"
18 | localport: "{{ item.port }}"
19 | action: allow
20 | direction: in
21 | protocol: tcp
22 | state: present
23 | enabled: yes
24 | when: inventory_hostname in groups['windows']
25 |
--------------------------------------------------------------------------------
/step5-deploy-multiple-spring-boot-apps-to-mixed-os-docker-swarm/spring-boot-app-health-check.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Defining needed variables
3 | set_fact:
4 | spring_boot_app:
5 | name: "{{ item.name }}"
6 | port: "{{ item.port }}"
7 |
8 | - name: Obtain the Docker Container´s internal IP address (because localhost doesn´t work for now https://github.com/docker/for-win/issues/458)
9 | win_shell: "docker inspect -f {% raw %}'{{ .NetworkSettings.Networks.nat.IPAddress }}' {% endraw %} springboot_{{spring_boot_app.name}}_1 {{ '>' }} container_ip.txt"
10 |
11 | - name: Get the Docker Container´s internal IP address from the temporary txt-file (we have to do this because of templating problems, see http://stackoverflow.com/a/32279729/4964553)
12 | win_shell: cat container_ip.txt
13 | register: win_shell_txt_return
14 |
15 | - name: Define the IP as variable
16 | set_fact:
17 | docker_container_ip: "{{ win_shell_txt_return.stdout.splitlines()[0] }}"
18 |
19 | - debug:
20 | msg: "The Docker Container that runs your App '{{spring_boot_app.name}}' has the internal IP {{ docker_container_ip }} --> Let´s do a health-check against this URI: 'http://{{ docker_container_ip }}:{{spring_boot_app.port}}/health'"
21 |
22 | # Spring Boot Actuators strange Content-Type 'application/vnd.spring-boot.actuator.v1+json' when calling
23 | # http://appname:port/health can be avoided by using the a correct header: 'Accept: application/json'
24 | # Doing so, the app reacts with a normal 'application/json' in the response and the healthcheck run's fine again :)
25 | - name: Wait until our Spring Boot app is up & running
26 | win_uri:
27 | url: "http://{{ docker_container_ip }}:{{spring_boot_app.port}}/health"
28 | method: GET
29 | headers:
30 | Accept: application/json
31 | register: health_result
32 | until: health_result.status_code == 200
33 | retries: 30
34 | delay: 20
35 | ignore_errors: yes
36 |
37 | - name: Show some more info, only when health check went wrong
38 | win_uri:
39 | url: "http://{{ docker_container_ip }}:{{spring_boot_app.port}}/health"
40 | method: GET
41 | register: health_bad_result
42 | ignore_errors: yes
43 | when: health_result|failed
44 |
45 | - name: Show some more info, only when health check went wrong
46 | debug:
47 | msg: "The app reacted with: {{health_bad_result}}"
48 | when: health_result|failed
49 |
50 |
--------------------------------------------------------------------------------
/step5-deploy-multiple-spring-boot-apps-to-mixed-os-docker-swarm/templates/Dockerfile-SpringBoot-Linux.j2:
--------------------------------------------------------------------------------
1 | FROM openjdk:8-jdk-alpine
2 |
3 | MAINTAINER Jonas Hecht
4 |
5 | VOLUME /tmp
6 |
7 | ENV REGISTRY_HOST {{spring_boot_app.registry_name}}
8 | ENV SPRINGBOOT_APP_NAME {{spring_boot_app.name}}
9 |
10 | # Add Spring Boot app.jar to Container
11 | ADD {{spring_boot_app.name}}.jar app.jar
12 |
13 | ENV JAVA_OPTS=""
14 |
15 | # Fire up our Spring Boot app by default
16 | ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar --server.port={{spring_boot_app.port}}" ]
--------------------------------------------------------------------------------
/step5-deploy-multiple-spring-boot-apps-to-mixed-os-docker-swarm/templates/Dockerfile-SpringBoot-Windows.j2:
--------------------------------------------------------------------------------
1 | #jinja2: newline_sequence:'\r\n'
2 | FROM springboot-oraclejre-nanoserver:latest
3 |
4 | MAINTAINER Jonas Hecht
5 |
6 | ENV REGISTRY_HOST {{spring_boot_app.registry_name}}
7 | ENV SPRINGBOOT_APP_NAME {{spring_boot_app.name}}
8 |
9 | # Add Spring Boot app.jar to Container
10 | ADD {{spring_boot_app.name}}.jar app.jar
11 |
12 | # Fire up our Spring Boot app by default
13 | CMD ["java.exe", "-jar app.jar --server.port={{spring_boot_app.port}}"]
--------------------------------------------------------------------------------
/step5-deploy-multiple-spring-boot-apps-to-mixed-os-docker-swarm/templates/docker-stack.j2:
--------------------------------------------------------------------------------
1 | #jinja2: newline_sequence:'\r\n'
2 | version: '3.4'
3 |
4 | services:
5 |
6 | {% for service in vars.services %}
7 | {{ service.name }}:
8 | image: {{registry_host}}/{{ service.name }}
9 | ports:
10 | - target: {{ service.port }}
11 | published: {{ service.port }}
12 | protocol: tcp
13 | tty:
14 | true
15 | restart:
16 | unless-stopped
17 | deploy:
18 | endpoint_mode: vip
19 | replicas: {{ service.replicas }}
20 | placement:
21 | {% if service.deploy_target == 'windows' %}
22 | constraints: [node.labels.os==windows]
23 | {% else %}
24 | constraints: [node.labels.os==linux]
25 | {% endif %}
26 | labels:
27 | - "traefik.port={{ service.port }}"
28 | - "traefik.docker.network={{ swarm_network_name }}"
29 | - "traefik.backend={{ service.name }}"
30 | # Use Traefik healthcheck "traefik.backend.healthcheck.path": "/healthcheck",
31 | - "traefik.frontend.rule=Host:{{ service.name }}.{{ docker_domain }}"
32 |
33 | {% endfor %}
34 |
35 | traefik:
36 | image: traefik
37 | ports:
38 | - target: 80
39 | published: 80
40 | protocol: tcp
41 | - target: 8080
42 | published: 8080
43 | protocol: tcp
44 | tty:
45 | true
46 | restart:
47 | unless-stopped
48 | deploy:
49 | replicas: 1
50 | placement:
51 | constraints: [node.labels.os==linux]
52 | constraints: [node.role == manager]
53 | command:
54 | - --docker
55 | - --docker.swarmmode
56 | - --docker.domain={{ docker_domain }}
57 | - --docker.watch
58 | - --web
59 | - --logLevel=INFO
60 | volumes:
61 | - type: bind
62 | source: /var/run/docker.sock
63 | target: /var/run/docker.sock
64 |
65 | networks:
66 | default:
67 | external:
68 | name: {{ swarm_network_name }}
--------------------------------------------------------------------------------