Skip to content

Commit

Permalink
Adding new step4 with docker-compose. This is only the first step, wh…
Browse files Browse the repository at this point in the history
…ich is not complete yet. For now, all the paths and jars of the Spring Boot services are prepared.
  • Loading branch information
jonashackt committed Mar 26, 2017
1 parent fa1cc1c commit 36e40cd
Show file tree
Hide file tree
Showing 14 changed files with 244 additions and 4 deletions.
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,21 @@ This will fire up multiple containers running Spring Boot Apps inside Docker Win
![spring-cloud-example-running-docker-windows-containers](https://github.com/jonashackt/ansible-windows-docker-springboot/blob/master/spring-cloud-example-running-docker-windows-containers.png)


## How to scale multiple Spring Boot Apps inside a Docker Windows Containers with Ansible, docker-compose and Spring Cloud Netflix ([step3-multiple-spring-boot-apps](https://github.com/jonashackt/ansible-windows-docker-springboot/tree/master/step4-multiple-spring-boot-apps-docker-compose))


Everything needed here is inside [step4-multiple-spring-boot-apps-docker-compose](https://github.com/jonashackt/ansible-windows-docker-springboot/tree/master/step4-multiple-spring-boot-apps-docker-compose). Be sure to have cloned and (Maven-) build the complete Spring Cloud example apps [spring-cloud-netflix-docker](https://github.com/jonashackt/spring-cloud-netflix-docker). Let´s cd into `step4-multiple-spring-boot-apps-docker-compose` and run the playbook:

```
ansible-playbook -i hostsfile ansible-windows-docker-springboot.yml --extra-vars "host=ansible-windows-docker-springboot-dev"
```

This will fire up multiple containers running Spring Boot Apps inside Docker Windows Containers on your Windows box. They will leverage the power of Spring Cloud Netflix with Zuul as a Proxy and Eureka as Service Registry (which dynamically tells Zuul, which Apps to route).

![spring-cloud-example-running-docker-windows-containers-docker-compose](https://github.com/jonashackt/ansible-windows-docker-springboot/blob/master/spring-cloud-example-running-docker-windows-containers-docker-compose.png)



## Best practices

##### Using Powershell on Host to Connect to Container
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,18 @@
port: 8091
jar_input_path: "../../spring-cloud-netflix-docker/weatherbackend/target/weatherbackend-0.0.1-SNAPSHOT.jar"

- name: Copy docker-compose.yml to directory C:\spring-boot (this is only additionally, compose isn´t necessary for the apps to run)
win_template:
src: "../../spring-cloud-netflix-docker/docker-compose.yml"
dest: "{{base_path}}\\docker-compose.yml"
- name: Run Weather Backend Service 3 (Spring Boot app) inside Windows-Docker-Container
include: spring-boot-app-windows-docker.yml
vars:
spring_boot_app:
name: weatherbackend-third
port: 8092
jar_input_path: "../../spring-cloud-netflix-docker/weatherbackend/target/weatherbackend-0.0.1-SNAPSHOT.jar"

- name: Run Weather Backend Service 4 (Spring Boot app) inside Windows-Docker-Container
include: spring-boot-app-windows-docker.yml
vars:
spring_boot_app:
name: weatherbackend-forth
port: 8093
jar_input_path: "../../spring-cloud-netflix-docker/weatherbackend/target/weatherbackend-0.0.1-SNAPSHOT.jar"
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
- hosts: "{{host}}"
vars:
base_path: "C:\\spring-boot"
service_registry_name: eureka-serviceregistry
services:
- name: eureka-serviceregistry
path_to_jar: "../../spring-cloud-netflix-docker/eureka-serviceregistry/target/eureka-serviceregistry-0.0.1-SNAPSHOT.jar"
port: 8761
- name: zuul-edgeservice
path_to_jar: "../../spring-cloud-netflix-docker/zuul-edgeservice/target/zuul-edgeservice-0.0.1-SNAPSHOT.jar"
port: 8080
- name: weatherbackend
path_to_jar: "../../spring-cloud-netflix-docker/weatherbackend/target/weatherbackend-0.0.1-SNAPSHOT.jar"
port: 8090
- name: weatherbackend-second
path_to_jar: "../../spring-cloud-netflix-docker/weatherbackend/target/weatherbackend-0.0.1-SNAPSHOT.jar"
port: 8090

tasks:
- name: Create base directory C:\spring-boot, if not there
win_file: path={{base_path}} state=directory

- name: Preparing the Spring Boot App´s Files for later docker-compose run
include: spring-boot-app-prepare.yml
with_items: "{{ vars.services }}"

- name: Template docker-compose.yml to directory C:\spring-boot
win_template:
src: "templates/docker-compose.j2"
dest: "{{base_path}}\\docker-compose.yml"

# Run docker-compose

# Do Healthchecks
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# http://docs.ansible.com/ansible/intro_windows.html#windows-how-does-it-work

ansible_port: 55986 # not 5986, as we would use for non-virtualized environments
ansible_connection: winrm

# The following is necessary for Python 2.7.9+ when using default WinRM self-signed certificates:
ansible_winrm_server_cert_validation: ignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# http://docs.ansible.com/ansible/intro_windows.html#windows-how-does-it-work

ansible_user: vagrant
ansible_password: vagrant
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# http://docs.ansible.com/ansible/intro_windows.html#windows-how-does-it-work

ansible_user: vagrant
ansible_password: vagrant
5 changes: 5 additions & 0 deletions step4-multiple-spring-boot-apps-docker-compose/hostsfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[ansible-windows-docker-springboot-dev]
127.0.0.1

[ansible-windows-docker-springboot-qa]
127.0.0.1
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
- name: Obtain the Docker Container´s internal IP address (because localhost doesn´t work for now https://github.com/docker/for-win/issues/458)
win_shell: "docker inspect -f {% raw %}'{{ .NetworkSettings.Networks.nat.IPAddress }}' {% endraw %} {{spring_boot_app.name}} {{ '>' }} container_ip.txt"

- 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)
win_shell: cat container_ip.txt
register: win_shell_txt_return

- name: Define the IP as variable
set_fact:
docker_container_ip: "{{ win_shell_txt_return.stdout.splitlines()[0] }}"

- debug:
msg: "Your Docker Container 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'"

###### Smoke test, if app has booted up correctly
- name: Wait until our Spring Boot app is up & running
win_uri:
url: "http://{{ docker_container_ip }}:{{spring_boot_app.port}}/health"
method: GET
register: health_result
until: health_result.status_code == 200
retries: 10
delay: 5
ignore_errors: yes

- name: Show some more info, only when health check went wrong
win_uri:
url: "http://{{ docker_container_ip }}:{{spring_boot_app.port}}/health"
method: GET
register: health_bad_result
ignore_errors: yes
when: health_result|failed

- name: Show some more info, only when health check went wrong
debug:
msg: "The app reacted with: {{health_bad_result}}"
when: health_result|failed

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
- name: Defining needed variables
set_fact:
spring_boot_app:
name: "{{ item.name }}"
port: "{{ item.port }}"
jar: "{{ item.path_to_jar }}"

- name: Preparing the following Spring Boot App´s Files for docker-compose run
debug:
msg: "Processing '{{spring_boot_app.name}}' with port '{{ spring_boot_app.port }}'"

- name: Create directory C:\spring-boot\spring_boot_app.name, if not there
win_file: path={{base_path}}\\{{spring_boot_app.name}} state=directory

- name: Template and copy Spring Boot app´s Dockerfile to directory C:\spring-boot\spring_boot_app.name
win_template:
src: "templates/Dockerfile-SpringBoot-App.j2"
dest: "{{base_path}}\\{{spring_boot_app.name}}\\Dockerfile"

- name: Copy Spring Boot app´s jar-File to directory C:\spring-boot\spring_boot_app.name
win_copy:
src: "{{spring_boot_app.jar}}"
dest: "{{base_path}}\\{{spring_boot_app.name}}\\{{spring_boot_app.name}}.jar"
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
- name: Preparing to run Spring Boot App in Docker Windows Container
debug:
msg: "Processing '{{spring_boot_app.name}}'"

- name: Define some needed variables
set_fact:
spring_boot_app_path: "{{base_path}}\\{{spring_boot_app.name}}"

- name: Create directory C:\spring-boot\spring_boot_app.name, if not there
win_file: path={{spring_boot_app_path}} state=directory

- name: Template and copy Spring Boot app´s Dockerfile to directory C:\spring-boot\spring_boot_app.name
win_template:
src: "templates/Dockerfile-SpringBoot-App.j2"
dest: "{{spring_boot_app_path}}\\Dockerfile"

- name: Copy Spring Boot app´s jar-File to directory C:\spring-boot\spring_boot_app.name
win_copy:
src: "{{jar_input_path}}"
dest: "{{spring_boot_app_path}}\\{{spring_boot_app.name}}.jar"

- name: Stop the Service Docker container
win_shell: docker stop {{spring_boot_app.name}}
ignore_errors: yes

- name: Remove the Service Docker container
win_shell: docker rm {{spring_boot_app.name}} --force
ignore_errors: yes

- name: Remove the Service Docker image
win_shell: docker rmi {{spring_boot_app.name}}:latest --force
ignore_errors: yes

- name: Build the Service Docker image
win_shell: docker build . --tag {{spring_boot_app.name}}:latest
args:
chdir: "{{spring_boot_app_path}}"

- name: Run the Service Docker container
win_shell: "docker run -d --publish {{spring_boot_app.port}}:{{spring_boot_app.port}} --name={{spring_boot_app.name}} --restart=unless-stopped {{spring_boot_app.name}}:latest"

- name: Healthchecking the Spring Boot app
include: spring-boot-app-health-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#jinja2: newline_sequence:'\r\n'
FROM springboot-oraclejre-nanoserver:latest

MAINTAINER Jonas Hecht

ENV REGISTRY_HOST {{service_registry_name}}
ENV SPRINGBOOT_APP_NAME {{spring_boot_app.name}}

# Expose the apps Port
EXPOSE {{spring_boot_app.port}}

# Add Spring Boot app.jar to Container
ADD {{spring_boot_app.name}}.jar app.jar

# Fire up our Spring Boot app by default
CMD ["java.exe", "-jar app.jar --server.port={{spring_boot_app.port}}"]

Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#jinja2: newline_sequence:'\r\n'
version: '3.1'

services:

eureka-serviceregistry:
build: ./eureka-serviceregistry
ports:
- "8761:8761"
tty:
true

# no portbinding here - the actual services should be accessible through Zuul proxy
weatherbackend:
build: ./weatherbackend
tty:
true

# no portbinding here - the actual services should be accessible through Zuul proxy
weatherbackend-second:
build: ./weatherbackend-second
tty:
true

zuul-edgeservice:
build: ./zuul-edgeservice
ports:
- "8080:8080"
tty:
true

networks:
default:
external:
name: "nat"

0 comments on commit 36e40cd

Please sign in to comment.