diff --git a/README.adoc b/README.adoc index 6a209d1fa..65b1e26ec 100644 --- a/README.adoc +++ b/README.adoc @@ -48,6 +48,8 @@ Use them at your own risk. == Deployment +=== From code + This application can be easily deployed using **Docker** and **docker-compose**. `$ docker-compose up` @@ -64,3 +66,13 @@ fdb63e26d299 mythaistar_angular "nginx -g 'daemon of…" 3 minu ``` The usage of the `reverse-proxy` only uses 1 port of the Docker host (where this is deployed), the `8080`. All internal communication of containers is done using docker alias of services. + +=== From artifact + +If we are using a CICD pipeline and we store the artifact on nexus, we can also deploy it without recompile all code. For this purpose there are three deployment pipelines: + +- deployment: deploy all application with a reserve-proxy +- java: deploy only the java application +- angular: deploy angular application + reverse-proxy (you must run the java deployment at least once before running this deployment) + +The result of this deployment will be the same as in the deployment from code, but instead of compiling the artifact again downloads it from nexus. All resources (docker-compose.yml, Dockerfiles and nginx.conf) are stored in the reverse-proxy folder. diff --git a/angular/Dockerfile b/angular/Dockerfile index 1bc7efabf..c2bdf59c5 100644 --- a/angular/Dockerfile +++ b/angular/Dockerfile @@ -5,14 +5,14 @@ COPY . /app RUN npm i -g @angular/cli RUN apk update && apk add yarn RUN yarn -RUN ng build --configuration=docker --prod --build-optimizer +RUN yarn build --configuration=docker # 2. Deploy FROM nginx:latest RUN apt-get update \ - && apt-get install -y --no-install-recommends \ - apache2-utils \ - && rm -rf /var/lib/apt/lists/* + && apt-get install -y --no-install-recommends \ + apache2-utils \ + && rm -rf /var/lib/apt/lists/* COPY nginx.conf /etc/nginx/conf.d/default.conf COPY --from=build /app/dist/. /usr/share/nginx/html EXPOSE 80 443 diff --git a/angular/package.json b/angular/package.json index 6f79d4dc6..edd6590ae 100644 --- a/angular/package.json +++ b/angular/package.json @@ -1,6 +1,6 @@ { "name": "mythaistar-restaurant", - "version": "1.12.0", + "version": "1.12.2", "main": "main.js", "scripts": { "postinstall": "npm run postinstall:electron && npx electron-builder install-app-deps", diff --git a/docker-compose.yml b/docker-compose.yml index dd83ebb79..7188d2f65 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,10 +1,11 @@ -version: '2' +version: '3' services: reverse-proxy: build: 'reverse-proxy/' restart: always container_name: 'mts_reverse_proxy' + image: my-thai-star/reverse-proxy:latest networks: - my-thai-star ports: @@ -13,14 +14,16 @@ services: build: 'angular/' restart: always container_name: 'mts_angular' + image: my-thai-star/angular:latest networks: - my-thai-star java: build: 'java/' restart: always container_name: 'mts_java' + image: my-thai-star/java:latest networks: - my-thai-star networks: my-thai-star: - driver: bridge \ No newline at end of file + driver: bridge diff --git a/java/Dockerfile b/java/Dockerfile index 939c06db7..6f10f9b1c 100644 --- a/java/Dockerfile +++ b/java/Dockerfile @@ -1,7 +1,7 @@ # 1. Build FROM maven:3.5-jdk-8-alpine AS build WORKDIR /app -COPY mtsj/. /app +COPY mtsj/ /app RUN ls -l RUN mvn install diff --git a/java/mtsj/api/pom.xml b/java/mtsj/api/pom.xml index b0d6bccea..bae2b3ac8 100644 --- a/java/mtsj/api/pom.xml +++ b/java/mtsj/api/pom.xml @@ -1,11 +1,12 @@ - + 4.0.0 com.devonfw.java.mtsj mtsj - 0.1-SNAPSHOT + 1.12.2-SNAPSHOT mtsj-api jar @@ -31,7 +32,7 @@ devon4j-jpa-envers - @@ -40,7 +41,7 @@ com.devonfw.java.modules devon4j-security - + org.hibernate.validator hibernate-validator diff --git a/java/mtsj/batch/pom.xml b/java/mtsj/batch/pom.xml index a6c0d2650..db69fa69c 100644 --- a/java/mtsj/batch/pom.xml +++ b/java/mtsj/batch/pom.xml @@ -1,11 +1,11 @@  - + 4.0.0 com.devonfw.java.mtsj mtsj - 0.1-SNAPSHOT + 1.12.2-SNAPSHOT mtsj-batch jar diff --git a/java/mtsj/core/pom.xml b/java/mtsj/core/pom.xml index 6ca8f74bf..adb840945 100644 --- a/java/mtsj/core/pom.xml +++ b/java/mtsj/core/pom.xml @@ -1,11 +1,11 @@  - + 4.0.0 com.devonfw.java.mtsj mtsj - 0.1-SNAPSHOT + 1.12.2-SNAPSHOT mtsj-core jar @@ -15,7 +15,7 @@ 1.8 h2 - h2mem + h2mem com.h2database h2 1.4.194 diff --git a/java/mtsj/pom.xml b/java/mtsj/pom.xml index 271a440bf..4467fe9e7 100644 --- a/java/mtsj/pom.xml +++ b/java/mtsj/pom.xml @@ -5,7 +5,7 @@ mtsj com.devonfw.java.mtsj - 0.1-SNAPSHOT + 1.12.2-SNAPSHOT pom ${project.artifactId} Application based on the Devonfw framework for Java (devon4j). diff --git a/java/mtsj/server/pom.xml b/java/mtsj/server/pom.xml index 683aecdb4..5bcd21fc1 100644 --- a/java/mtsj/server/pom.xml +++ b/java/mtsj/server/pom.xml @@ -1,11 +1,11 @@  - + 4.0.0 com.devonfw.java.mtsj mtsj - 0.1-SNAPSHOT + 1.12.2-SNAPSHOT mtsj-server war @@ -122,7 +122,7 @@ ${server.war.name} - + ${project.basedir}/src/main/resources diff --git a/jenkins/README.md b/jenkins/README.md index ed63ea684..ce8ebbee4 100644 --- a/jenkins/README.md +++ b/jenkins/README.md @@ -148,6 +148,7 @@ In order to run all pipelines, we have installed the following plugins (maybe no - Xvnc plugin (xvnc) - Dashboard for Blue Ocean (blueocean-dashboard) - Script Security Plugin (script-security) +- **HTTP Request Plugin (http_request)** Most of them come pre-installed with the production line instance. The ones we need are the ones related to the pipeline and the ones in bold. @@ -169,6 +170,22 @@ Most of them come pre-installed with the production line instance. The ones we n You only need to create a new pipeline and modify the configuration following the image: ![](./pipeline-config.png) +Or you can execute the create-pipelines.sh as follows: + +```bash +$ ./create-pipelines.sh +``` + +example: + +```bash +$ ./create-pipelines.sh devon.s2-eu.capgemini.com/jenkins devonfw capgemini +``` + +**Important:** you need a bash shell in order to execute the command. If you are using windows, you can open a new bash shell in the devonfw console: +![console](./console.png) + + **TIP**: All environment variables used on both Jenkinsfiles should be declared in the correspondant Jenkins Pipeline configuration more or less like this: ![](./jenkins-pipelines-params.png) diff --git a/jenkins/angular/cicd/Jenkinsfile b/jenkins/angular/cicd/Jenkinsfile index d2ccc3694..3b4d536c1 100644 --- a/jenkins/angular/cicd/Jenkinsfile +++ b/jenkins/angular/cicd/Jenkinsfile @@ -13,7 +13,7 @@ pipeline{ environment { // Script for build the application. Defined at package.json - buildScript = 'build:prodcompose' + buildScript = 'build --configuration=docker' // Script for lint the application. Defined at package.json lintScript = 'lint' // Script for test the application. Defined at package.json diff --git a/jenkins/angular/cicd/pipeline.xml b/jenkins/angular/cicd/pipeline.xml new file mode 100644 index 000000000..e4d6d8a66 --- /dev/null +++ b/jenkins/angular/cicd/pipeline.xml @@ -0,0 +1,28 @@ + + + + false + + + + 2 + + + https://github.com/dario-rodriguez/my-thai-star.git + + + + + */cicd-and-deployment + + + false + + + + jenkins/angular/cicd/Jenkinsfile + true + + + false + \ No newline at end of file diff --git a/jenkins/angular/deployment/Jenkinsfile b/jenkins/angular/deployment/Jenkinsfile new file mode 100644 index 000000000..9cc0d79f2 --- /dev/null +++ b/jenkins/angular/deployment/Jenkinsfile @@ -0,0 +1,92 @@ +pipeline{ + agent any + + options { + buildDiscarder(logRotator(artifactDaysToKeepStr: '1', artifactNumToKeepStr: '1', daysToKeepStr: '5', numToKeepStr: '50')) + // Disable concurrent builds. It will wait until the pipeline finish before start a new one + disableConcurrentBuilds() + } + + environment { + // Jenkins credentials id for ssh agent + sshAgentCredentials = '3d0fa2a4-5cf0-4cf5-a3fd-23655eb33c11' + + // Nexus3 API url + nexusApiUrl = 'devon.s2-eu.capgemini.com/nexus3/' + // Maven repository + repository = 'snapshots' + // Repository format + format = 'maven2' + // Artifact group + group = 'com.devonfw.mythaistar' + // Application name + name = 'mythaistar-restaurant' + // Artifact extension + extension = 'zip' + } + + parameters { + string(name: 'VERSION', defaultValue: '1.12.0-SNAPSHOT', description: 'Version number') + string(name: 'EXTERNAL_SERVER_IP', defaultValue: '10.40.235.244', description: 'Server IP') + string(name: 'APPLICATION_DIR', defaultValue: '/root/mythaistar/reverse-proxy/', description: 'My Thai Star application directory') + } + + stages { + stage ('Download artifact from Nexus') { + steps { + script { + // Download artifact from nexus3 using the nexus3 beta api + withCredentials([usernamePassword(credentialsId: 'pl-technical-user', passwordVariable: 'pass', usernameVariable: 'user')]) { + // Search the list of artifacts + def response = httpRequest """https://${user}:${pass}@${nexusApiUrl}service/rest/beta/search/assets?repository=${repository}&format=${format}&group=${group}&name=${name}&maven.groupId=${group}&maven.artifactId=${name}&maven.baseVersion=${params.VERSION}&maven.extension=${extension}""" + def props = readJSON text: response.content + + // Get the last snapshot download url + def num = -1 + def url = '' + props.items.each { + def n = (it.downloadUrl =~ /.*-(\d*)\.zip/)[0][1] + if (n > num) { + num = n + url = it.downloadUrl + } + } + + // Download the snapshot + sh """wget -O ${name}-${params.VERSION}.${extension} ${url.replace('https://','https://'+user+':'+pass+'@')}""" + + // Unzip the angular application + sh "mkdir -p dist" + unzip dir: 'dist', zipFile: """${name}-${params.VERSION}.${extension}""" + } + } + } + } + + stage ('Deployment') { + steps { + script { + dir('dist'){ + sshagent (credentials: [sshAgentCredentials]) { + sh """ + # Copy resulting "dist" folder from workspace to deployment server + ssh -o StrictHostKeyChecking=no root@${params.EXTERNAL_SERVER_IP} mkdir -p ${params.APPLICATION_DIR}angular/dist/ + ssh -o StrictHostKeyChecking=no root@${params.EXTERNAL_SERVER_IP} rm -r ${params.APPLICATION_DIR}angular/dist/* 2> /dev/null + scp -o StrictHostKeyChecking=no -r . root@${params.EXTERNAL_SERVER_IP}:${params.APPLICATION_DIR}angular/dist/ + + # Launch application in Docker container + ssh -o StrictHostKeyChecking=no root@${params.EXTERNAL_SERVER_IP} docker-compose -f ${params.APPLICATION_DIR}docker-compose.yml up -d --build + """ + } + } + } + } + } + } + + post { + always { + cleanWs() + } + } +} \ No newline at end of file diff --git a/jenkins/angular/deployment/pipeline.xml b/jenkins/angular/deployment/pipeline.xml new file mode 100644 index 000000000..c654ab0fc --- /dev/null +++ b/jenkins/angular/deployment/pipeline.xml @@ -0,0 +1,28 @@ + + + + false + + + + 2 + + + https://github.com/dario-rodriguez/my-thai-star.git + + + + + */cicd-and-deployment + + + false + + + + jenkins/deployment/cicd/Jenkinsfile + true + + + false + \ No newline at end of file diff --git a/jenkins/console.png b/jenkins/console.png new file mode 100644 index 000000000..0cf5048f3 Binary files /dev/null and b/jenkins/console.png differ diff --git a/jenkins/create-pipelines.sh b/jenkins/create-pipelines.sh new file mode 100644 index 000000000..ee638b8a8 --- /dev/null +++ b/jenkins/create-pipelines.sh @@ -0,0 +1,20 @@ + +if [ $# -ne 3 ] +then + echo "Please invoke this script with three arguments." + echo "create-pipelines " + exit -1 +fi + +JENKINS_URL=$1 +REQUEST="https://$JENKINS_URL" +ENDING='/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)' +CRUMB=$(curl -s "$REQUEST$ENDING" -u $2:$3) +curl -s -XPOST "https://$JENKINS_URL/createItem?name=MTS" -u $2:$3 --data-binary @./folder.xml -H "$CRUMB" -H "Content-Type:text/xml" +curl -s -XPOST "https://$JENKINS_URL/job/MTS/createItem?name=CICD" -u $2:$3 --data-binary @./folder.xml -H "$CRUMB" -H "Content-Type:text/xml" +curl -s -XPOST "https://$JENKINS_URL/job/MTS/createItem?name=deployment" -u $2:$3 --data-binary @./folder.xml -H "$CRUMB" -H "Content-Type:text/xml" +curl -s -XPOST "https://$JENKINS_URL/job/MTS/job/CICD/createItem?name=angular" -u $2:$3 --data-binary @./angular/cicd/pipeline.xml -H "$CRUMB" -H "Content-Type:text/xml" +curl -s -XPOST "https://$JENKINS_URL/job/MTS/job/CICD/createItem?name=java" -u $2:$3 --data-binary @./java/cicd/pipeline.xml -H "$CRUMB" -H "Content-Type:text/xml" +curl -s -XPOST "https://$JENKINS_URL/job/MTS/job/deployment/createItem?name=angular" -u $2:$3 --data-binary @./angular/deployment/pipeline.xml -H "$CRUMB" -H "Content-Type:text/xml" +curl -s -XPOST "https://$JENKINS_URL/job/MTS/job/deployment/createItem?name=java" -u $2:$3 --data-binary @./java/deployment/pipeline.xml -H "$CRUMB" -H "Content-Type:text/xml" +curl -s -XPOST "https://$JENKINS_URL/job/MTS/job/deployment/createItem?name=deployment" -u $2:$3 --data-binary @./deployment/pipeline.xml -H "$CRUMB" -H "Content-Type:text/xml" \ No newline at end of file diff --git a/jenkins/deployment/Jenkinsfile b/jenkins/deployment/Jenkinsfile new file mode 100644 index 000000000..0417b666c --- /dev/null +++ b/jenkins/deployment/Jenkinsfile @@ -0,0 +1,60 @@ +pipeline{ + agent any + + options { + buildDiscarder(logRotator(artifactDaysToKeepStr: '1', artifactNumToKeepStr: '1', daysToKeepStr: '5', numToKeepStr: '50')) + // Disable concurrent builds. It will wait until the pipeline finish before start a new one + disableConcurrentBuilds() + } + + environment { + // Jenkins credentials id for ssh agent + sshAgentCredentials = '3d0fa2a4-5cf0-4cf5-a3fd-23655eb33c11' + + // Java Deploy Pipeline name + javaDeployPipeline = 'java' + // Angular Deploy Pipeline name + angularDeployPipeline = 'angular' + } + + parameters { + string(name: 'JAVA_VERSION', defaultValue: '0.1-SNAPSHOT', description: 'Java Version number') + string(name: 'ANGULAR_VERSION', defaultValue: '1.12.0-SNAPSHOT', description: 'Angulalr Version number') + string(name: 'EXTERNAL_SERVER_IP', defaultValue: '10.40.235.244', description: 'Server IP') + string(name: 'APPLICATION_DIR', defaultValue: '/root/mythaistar/reverse-proxy/', description: 'My Thai Star application directory') + } + + + stages { + stage ('Copy files to remote server') { + steps { + sshagent (credentials: [sshAgentCredentials]) { + sh """ + ssh -o StrictHostKeyChecking=no root@${params.EXTERNAL_SERVER_IP} mkdir -p ${params.APPLICATION_DIR} + scp -o StrictHostKeyChecking=no -r reverse-proxy/ root@${params.EXTERNAL_SERVER_IP}:${params.APPLICATION_DIR} + """ + } + } + } + + stage ('Deploy java application') { + steps { + build job: javaDeployPipeline, parameters: [ + string(name: 'VERSION', value: params.JAVA_VERSION), + string(name: 'EXTERNAL_SERVER_IP', value: params.EXTERNAL_SERVER_IP), + string(name: 'APPLICATION_DIR', value: params.APPLICATION_DIR) + ] + } + } + + stage ('Deploy angular application') { + steps { + build job: angularDeployPipeline, parameters: [ + string(name: 'VERSION', value: params.ANGULAR_VERSION), + string(name: 'EXTERNAL_SERVER_IP', value: params.EXTERNAL_SERVER_IP), + string(name: 'APPLICATION_DIR', value: params.APPLICATION_DIR) + ] + } + } + } +} \ No newline at end of file diff --git a/jenkins/deployment/pipeline.xml b/jenkins/deployment/pipeline.xml new file mode 100644 index 000000000..008f1d8bd --- /dev/null +++ b/jenkins/deployment/pipeline.xml @@ -0,0 +1,28 @@ + + + + false + + + + 2 + + + https://github.com/dario-rodriguez/my-thai-star.git + + + + + */cicd-and-deployment + + + false + + + + jenkins/deployment/Jenkinsfile + true + + + false + \ No newline at end of file diff --git a/jenkins/folder.xml b/jenkins/folder.xml new file mode 100644 index 000000000..d8e46f537 --- /dev/null +++ b/jenkins/folder.xml @@ -0,0 +1,22 @@ + + + + + + + + All + false + false + + + + + + + + false + + + + \ No newline at end of file diff --git a/jenkins/java/cicd/pipeline.xml b/jenkins/java/cicd/pipeline.xml new file mode 100644 index 000000000..0e64c9a1e --- /dev/null +++ b/jenkins/java/cicd/pipeline.xml @@ -0,0 +1,28 @@ + + + + false + + + + 2 + + + https://github.com/dario-rodriguez/my-thai-star.git + + + + + */cicd-and-deployment + + + false + + + + jenkins/java/cicd/Jenkinsfile + true + + + false + \ No newline at end of file diff --git a/jenkins/java/deployment/Jenkinsfile b/jenkins/java/deployment/Jenkinsfile new file mode 100644 index 000000000..7b4186bfd --- /dev/null +++ b/jenkins/java/deployment/Jenkinsfile @@ -0,0 +1,87 @@ +pipeline{ + agent any + + options { + buildDiscarder(logRotator(artifactDaysToKeepStr: '1', artifactNumToKeepStr: '1', daysToKeepStr: '5', numToKeepStr: '50')) + // Disable concurrent builds. It will wait until the pipeline finish before start a new one + disableConcurrentBuilds() + } + + environment { + // Jenkins credentials id for ssh agent + sshAgentCredentials = '3d0fa2a4-5cf0-4cf5-a3fd-23655eb33c11' + + // Nexus3 API url + nexusApiUrl = 'devon.s2-eu.capgemini.com/nexus3/' + // Nexus3 credentials ID + nexusCredentialsId = 'pl-technical-user' + // Maven artifact classifier + classifier = 'bootified' + // Maven repository + repository = 'snapshots' + // Repository format + format = 'maven2' + // Artifact group + group = 'com.devonfw.java.mtsj' + // Application name + name = 'mtsj-server' + // Artifact extension + extension = 'war' + } + + parameters { + string(name: 'VERSION', defaultValue: '0.1-SNAPSHOT', description: 'Version number') + string(name: 'EXTERNAL_SERVER_IP', defaultValue: '10.40.235.244', description: 'Server IP') + string(name: 'APPLICATION_DIR', defaultValue: '/root/mythaistar/reverse-proxy/', description: 'My Thai Star application directory') + } + + stages { + stage ('Download artifact from Nexus') { + steps { + script { + // Download artifact from nexus3 using the nexus3 beta api + withCredentials([usernamePassword(credentialsId: nexusCredentialsId, passwordVariable: 'pass', usernameVariable: 'user')]) { + // Search the list of artifacts + def response = httpRequest """https://${user}:${pass}@${nexusApiUrl}service/rest/beta/search/assets?repository=${repository}&format=${format}&group=${group}&name=${name}&maven.groupId=${group}&maven.artifactId=${name}&maven.baseVersion=${params.VERSION}&maven.classifier=${classifier}&maven.extension=${extension}""" + def props = readJSON text: response.content + + // Get the last snapshot download url + def num = -1 + def url = '' + props.items.each { + def n = (it.downloadUrl =~ /.*-(\d*)-bootified\.war/)[0][1] + println n + if (n > num) { + num = n + url = it.downloadUrl + } + } + + // Download the snapshot + sh """wget -O mythaistar.war ${url.replace('https://','https://'+user+':'+pass+'@')}""" + } + } + } + } + + stage('Deployment') { + steps { + sshagent (credentials: ['3d0fa2a4-5cf0-4cf5-a3fd-23655eb33c11']) { + sh """ + # Copy resulting ".war" file from workspace to deployment server + scp -o StrictHostKeyChecking=no -r mythaistar.war root@${params.EXTERNAL_SERVER_IP}:${params.APPLICATION_DIR}java/ + + # Launch application in Docker container + ssh -o StrictHostKeyChecking=no root@${params.EXTERNAL_SERVER_IP} docker-compose -f ${params.APPLICATION_DIR}docker-compose.yml up -d --build java + """ + } + } + } + } + + post { + always { + cleanWs() + } + } +} \ No newline at end of file diff --git a/jenkins/java/deployment/pipeline.xml b/jenkins/java/deployment/pipeline.xml new file mode 100644 index 000000000..63153166d --- /dev/null +++ b/jenkins/java/deployment/pipeline.xml @@ -0,0 +1,28 @@ + + + + false + + + + 2 + + + https://github.com/dario-rodriguez/my-thai-star.git + + + + + */cicd-and-deployment + + + false + + + + jenkins/java/deployment/Jenkinsfile + true + + + false + \ No newline at end of file diff --git a/jenkins/node/cicd/Jenkinsfile b/jenkins/node/cicd/Jenkinsfile index 3931107f5..fef72cf2e 100644 --- a/jenkins/node/cicd/Jenkinsfile +++ b/jenkins/node/cicd/Jenkinsfile @@ -12,22 +12,33 @@ pipeline{ } environment { + // Script for build the application. Defined at package.json buildScript = "compile" + // Script for lint the application. Defined at package.json lintScript = "lint" + // Script for test the application. Defined at package.json testScript = "test" + // Node project directory nodeDir = "node" // sonarQube + // Name of the sonarQube tool sonarTool = 'SonarQube-scanner' + // Name of the sonarQube environment sonarEnv = "SonarQube" // Nexus - artifactId = 'my-thai-star' + // Artifact groupId groupId = 'com.devonfw.mythaistar' + // Nexus repository ID repositoryId = 'devon.snapshots' + // Nexus internal URL repositoryUrl = 'http://nexus3-core:8081/nexus3/repository/snapshots' + // Maven global settings ID mavenGlobalSettings = '9d437f6e-46e7-4a11-a8d1-2f0055f14033' + // JavaJDK tool id javaJdk = 'Java8' + // Maven tool id mavenInstallation = 'Maven3' } diff --git a/node/package.json b/node/package.json index 3ff2b397c..70cb82c1d 100644 --- a/node/package.json +++ b/node/package.json @@ -1,6 +1,6 @@ { "name": "my-thai-star", - "version": "0.0.1", + "version": "1.12.2", "description": "server template for Devon4Node", "authors": [ "mmaganam", @@ -97,4 +97,4 @@ "src" ] } -} +} \ No newline at end of file diff --git a/reverse-proxy/Dockerfile b/reverse-proxy/Dockerfile index c0ee17de7..17db4324b 100644 --- a/reverse-proxy/Dockerfile +++ b/reverse-proxy/Dockerfile @@ -1,9 +1,3 @@ FROM nginx:latest -RUN apt-get update \ - && apt-get install -y --no-install-recommends \ - apache2-utils \ - && rm -rf /var/lib/apt/lists/* -COPY nginx.conf /etc/nginx/conf.d/default.conf -EXPOSE 80 -CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file +COPY nginx.conf /etc/nginx/conf.d/default.conf diff --git a/reverse-proxy/angular/Dockerfile b/reverse-proxy/angular/Dockerfile new file mode 100644 index 000000000..0fb2df37a --- /dev/null +++ b/reverse-proxy/angular/Dockerfile @@ -0,0 +1,4 @@ +FROM nginx:latest + +COPY nginx.conf /etc/nginx/nginx.conf +COPY ./dist/ /var/www/ \ No newline at end of file diff --git a/reverse-proxy/angular/nginx.conf b/reverse-proxy/angular/nginx.conf new file mode 100644 index 000000000..8f01a44fd --- /dev/null +++ b/reverse-proxy/angular/nginx.conf @@ -0,0 +1,51 @@ +# Generated by nginxconfig.io +# https://nginxconfig.io/?domain=_&document_root=%2Ffrontend&https=false&redirect=false&fallback_html&php=false&file_structure=unified&symlink=false&proxy&proxy_pass=http:%2F%2Fjava:8081 + +events { + multi_accept on; + worker_connections 65535; +} + +http { + charset utf-8; + sendfile on; + tcp_nopush on; + tcp_nodelay on; + server_tokens off; + log_not_found off; + types_hash_max_size 2048; + client_max_body_size 16M; + + # MIME + include mime.types; + default_type application/octet-stream; + + # logging + access_log /var/log/nginx/access.log; + error_log /var/log/nginx/error.log warn; + + # _ + server { + listen 80; + listen [::]:80; + + server_name _; + root /var/www/; + + try_files $uri $uri/ /index.html; + + # security headers + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header X-Content-Type-Options "nosniff" always; + add_header Referrer-Policy "no-referrer-when-downgrade" always; + add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always; + + # gzip + gzip on; + gzip_vary on; + gzip_proxied any; + gzip_comp_level 6; + gzip_types text/plain text/css text/xml application/json application/javascript application/xml+rss application/atom+xml image/svg+xml; + } +} diff --git a/reverse-proxy/docker-compose.yml b/reverse-proxy/docker-compose.yml new file mode 100644 index 000000000..da79390a6 --- /dev/null +++ b/reverse-proxy/docker-compose.yml @@ -0,0 +1,29 @@ +version: '3' +services: + reverse-proxy: + build: . + image: my-thai-star/reverse-proxy:latest + restart: always + ports: + - '8088:80' + networks: + - my-thai-star + depends_on: + - java + - angular + java: + build: java/ + image: my-thai-star/java:latest + restart: always + networks: + - my-thai-star + angular: + build: angular/ + image: my-thai-star/angular:latest + restart: always + networks: + - my-thai-star + +networks: + my-thai-star: + driver: bridge diff --git a/reverse-proxy/java/Dockerfile b/reverse-proxy/java/Dockerfile new file mode 100644 index 000000000..9b8b67d6f --- /dev/null +++ b/reverse-proxy/java/Dockerfile @@ -0,0 +1,5 @@ +FROM java:8 +WORKDIR /app +COPY ./mythaistar.war /app/ +ENTRYPOINT ["java","-jar","/app/mythaistar.war"] +EXPOSE 8081 \ No newline at end of file diff --git a/reverse-proxy/nginx.conf b/reverse-proxy/nginx.conf index 1bdbfcd58..87bb53374 100644 --- a/reverse-proxy/nginx.conf +++ b/reverse-proxy/nginx.conf @@ -1,14 +1,38 @@ server { - server_name devonfw-reverse-proxy.dev; + server_name _; root /usr/share/nginx/html; - location / { - proxy_pass http://angular:80; - } + # reverse proxy + location / { + proxy_pass http://angular:80; + proxy_http_version 1.1; + proxy_cache_bypass $http_upgrade; + + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Port $server_port; + } - location /api { - proxy_pass http://java:8081/mythaistar; - } + # reverse proxy + location /api { + proxy_pass http://java:8081/mythaistar; + proxy_http_version 1.1; + proxy_cache_bypass $http_upgrade; + + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Port $server_port; + } error_log /var/log/nginx/devonfw_reverseproxy_error.log; access_log /var/log/nginx/devonfw_reverseproxy_access.log;