├── .gitignore ├── README.md ├── pom.xml └── src └── main ├── docker ├── Dockerfile └── docker-compose.yml ├── java └── com │ └── sap │ └── docker │ └── MainServlet.java ├── kubernetes └── helm-chart │ ├── Chart.yaml │ ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── deployment.yaml │ └── service.yaml │ └── values.yaml └── webapp └── WEB-INF └── web.xml /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | .idea/ 3 | *.iml 4 | *.war -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | docker-java-sample-webapp 2 | ========================= 3 | 4 | ## Getting started 5 | 6 | - Build the java app 7 | 8 | `mvn clean install` 9 | 10 | - Take the war file from `target` & put it into `src/main/docker` directory. 11 | 12 | ## Docker commands approach 13 | 14 | - Go into `src/main/docker` directory 15 | 16 | - Build the docker image 17 | 18 | `docker build -t tomcat:1 .` 19 | 20 | - Run the image inside a container 21 | 22 | `docker container run -p 8080:8080 tomcat:1` 23 | 24 | - Go to `http://localhost:8080/docker-java-sample-webapp-1.0-SNAPSHOT?name=World` & see the app running in docker 25 | 26 | - List all containers 27 | 28 | `docker container ls` 29 | 30 | - Stop container 31 | 32 | `docker container kill ` 33 | 34 | - Remove container 35 | 36 | `docker rm ` 37 | 38 | - List all images 39 | 40 | `docker images` 41 | 42 | - Remove image 43 | 44 | `docker rmi tomcat:1` 45 | 46 | - Remove base image 47 | 48 | `docker rmi bitnami/tomcat:latest` 49 | 50 | ## Docker compose approach 51 | 52 | - Go into `src/main/docker` directory 53 | 54 | - Execute the command 55 | 56 | `docker-compose up` 57 | 58 | - When it is stopped, the corresponding containers are deleted also. But images remain. They have to be deleted using commands. 59 | 60 | ## Kubernetes approach 61 | 62 | - Use docker edge channel. It has inbuilt kubernetes support. 63 | 64 | - To get kubernetes dashboard running 65 | 66 | - `kubectl cluster-info` 67 | - `kubectl -n kube-system edit service kubernetes-dashboard` 68 | - `You should see yaml representation of the service. Change type: ClusterIP to type: NodePort and save file. If it's already changed go to next step.` 69 | - `kubectl -n kube-system get service kubernetes-dashboard` 70 | 71 | - Now deploy the war 72 | 73 | - Use helm 2.8.2 74 | - `helm.exe install .` 75 | 76 | - To delete entire deployment 77 | - `kubectl delete deployment kissing-fish-java-sample-webapp` 78 | 79 | 80 | ## Extras 81 | 82 | - Log into the container 83 | 84 | `docker exec -it [container-id] bash` -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.sap.docker 8 | docker-java-sample-webapp 9 | 1.0-SNAPSHOT 10 | war 11 | 12 | 13 | 14 | central-maven 15 | central-maven 16 | http://central.maven.org/maven2/ 17 | 18 | 19 | 20 | 21 | 22 | javax.servlet 23 | servlet-api 24 | 2.5 25 | 26 | 27 | 28 | 29 | 30 | 31 | org.apache.maven.plugins 32 | maven-compiler-plugin 33 | 3.6.2 34 | 35 | 1.8 36 | 1.8 37 | 38 | 39 | 40 | org.eclipse.jetty 41 | jetty-maven-plugin 42 | 9.4.9.v20180320 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /src/main/docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM bitnami/tomcat:latest 2 | 3 | COPY docker-java-sample-webapp-1.0-SNAPSHOT.war /bitnami/tomcat/data/ -------------------------------------------------------------------------------- /src/main/docker/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | web: 4 | image: 'java-sample-webapp' 5 | build: . 6 | ports: 7 | - "8080:8080" -------------------------------------------------------------------------------- /src/main/java/com/sap/docker/MainServlet.java: -------------------------------------------------------------------------------- 1 | package com.sap.docker; 2 | 3 | import javax.servlet.ServletException; 4 | import javax.servlet.http.HttpServlet; 5 | import javax.servlet.http.HttpServletRequest; 6 | import javax.servlet.http.HttpServletResponse; 7 | import java.io.IOException; 8 | 9 | public class MainServlet extends HttpServlet { 10 | 11 | @Override 12 | protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 13 | super.doPost(req, resp); 14 | } 15 | 16 | @Override 17 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 18 | String name = req.getParameter("name"); 19 | resp.getWriter().write("Hello " + name); 20 | resp.getWriter().close(); 21 | } 22 | } -------------------------------------------------------------------------------- /src/main/kubernetes/helm-chart/Chart.yaml: -------------------------------------------------------------------------------- 1 | description: java webapp helm chart 2 | name: java-sample-webapp 3 | version: 0.1.0 -------------------------------------------------------------------------------- /src/main/kubernetes/helm-chart/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | 1. Get the application URL by running these commands: 2 | 3 | {{- if contains "NodePort" .Values.service.type }} 4 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "fullname" . }}) 5 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") 6 | echo http://$NODE_IP:$NODE_PORT/jhipster 7 | {{- else if contains "LoadBalancer" .Values.service.type }} 8 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 9 | You can watch the status of by running 'kubectl get svc -w {{ template "fullname" . }}' 10 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') 11 | echo http://$SERVICE_IP:{{ .Values.service.externalPort }} 12 | {{- else if contains "ClusterIP" .Values.service.type }} 13 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "fullname" . }}" -o jsonpath="{.items[0].metadata.name}") 14 | echo "Visit http://127.0.0.1:8080/ to use your application" 15 | kubectl port-forward $POD_NAME 8080:{{ .Values.service.externalPort }} 16 | {{- end }} -------------------------------------------------------------------------------- /src/main/kubernetes/helm-chart/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | */}} 13 | {{- define "fullname" -}} 14 | {{- $name := default .Chart.Name .Values.nameOverride -}} 15 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 16 | {{- end -}} -------------------------------------------------------------------------------- /src/main/kubernetes/helm-chart/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: {{ template "fullname" . }} 5 | labels: 6 | chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}" 7 | spec: 8 | replicas: {{ .Values.replicaCount }} 9 | template: 10 | metadata: 11 | labels: 12 | app: {{ template "fullname" . }} 13 | spec: 14 | containers: 15 | - name: {{ .Chart.Name }} 16 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" 17 | imagePullPolicy: {{ .Values.image.pullPolicy }} 18 | ports: 19 | - name: http 20 | containerPort: {{ .Values.service.internalPort }} -------------------------------------------------------------------------------- /src/main/kubernetes/helm-chart/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ template "fullname" . }} 5 | labels: 6 | chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}" 7 | spec: 8 | type: {{ .Values.service.type }} 9 | ports: 10 | - port: {{ .Values.service.externalPort }} 11 | targetPort: {{ .Values.service.internalPort }} 12 | protocol: TCP 13 | name: {{ .Values.service.name }} 14 | selector: 15 | app: {{ template "fullname" . }} -------------------------------------------------------------------------------- /src/main/kubernetes/helm-chart/values.yaml: -------------------------------------------------------------------------------- 1 | replicaCount: 1 2 | image: 3 | repository: java-sample-webapp 4 | tag: latest 5 | pullPolicy: IfNotPresent 6 | service: 7 | name: tomcat 8 | type: NodePort 9 | externalPort: 8080 10 | internalPort: 8080 11 | 12 | resources: 13 | limits: 14 | cpu: 100m 15 | memory: 128Mi 16 | requests: 17 | cpu: 100m 18 | memory: 128Mi -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | Docker Java Sample Webapp 9 | 10 | A simple webapp for docker tests 11 | 12 | 13 | 14 | MainServlet 15 | com.sap.docker.MainServlet 16 | 17 | 18 | 19 | MainServlet 20 | /* 21 | 22 | 23 | --------------------------------------------------------------------------------