diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..20f3885 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,22 @@ +pipeline{ + agent any + stages{ + stage('---build---'){ + steps{ + sh "docker-compose build" + } + } + stage('---push---'){ + steps{ + sh "docker-compose push" + } + } + stage('---deploy---'){ + steps{ + sh "docker stack deploy --compose-file docker-compose.yaml devops" + } + } + } +} + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..aa4fa2d --- /dev/null +++ b/README.md @@ -0,0 +1,238 @@ +# Little Anchorage Financial Bank: DevOps Project + +In fulfilment of the group DevOps project assignment due Monday week 11 at QA consulting. + +## Index +[Brief](#brief) + +[Architecture](#architecture) + +[Technologies Used](#tech) + +[Deployment](#depl) + * [Prerequisites and Installation Guide](#prereq) + * [CI Pipeline](#CI) + +[Authors](#auth) + +[Acknowledgements](#ack) + + +# The Brief + + + + +# Architecture +### Before + +### After + + +## Technologies Used + +* Mongo - Database +* Node - creating the account generator which includes generating the prize +* Python - creating the number and text generator which generates an account number +* Jenkins - CI Server +* [Git](https://github.com/ayshamarty/SoloProject.git) - VCS +* [Trello](https://trello.com/b/yf6TuPx0/devops-project) - Project Tracking +* Azure - Live Environment +* Docker-Compose - builds the images used to create our containers +* [DockerHub](https://cloud.docker.com/u/keepkarm/repository/list) - registry for storing and updating images used for deployment +* Docker Swarm + + +# Deployment + + +## Prerequisites +* An Azure virtual machine with Jenkins, Docker and Docker-Compose installed +* At least one other Azure virtual machine with Docker installed +* Access to a Dockerhub registry + +## Installing Jenkins, Docker and Docker Compose, and setting up the swarm + +### Setting up the project: + +1. Create a new resource group: + +
+ + az group create –name devops -l uksouth + +
+ +2. Create a new virtual machine: + ++ + az vm create -g devops -n ManagerNode --image UbuntuLTS -l uksouth + +*repeat this command at least once to create your worker nodes, renaming the machines in the -n tag (eg -n Worker1)* + +
+ +3. Clone down the project within your ManagerNode + ++ + git clone https://github.com/kryan1622/LAFB.git + +
+ +4. Install docker and jenkins with with the included scripts and follow the instructions + ++ + sh ~/LAFB/installation/docker.sh + +*remember to copy this script and run it on your worker nodes* + + sh ~/LAFB/installation/jenkins.sh + +
+ +### Building the images + +1. Build docker images + ++ + docker-compose build + +
+ +2. Push docker images to the desired dockerhub account by first logging onto dockerhub within the virtual machine ++ + docker login + +*Enter username and password when requested* + + docker-compose push + +
+ +### Setting up the swarm + +1. Initialise your swarm in the manager node + ++ + docker swarm init + +*this will return a command with a unique token which you can run in any number of other virtual machines to set them up as your worker nodes* + +
+ +2. Deploy containers with the built images in docker swarm + ++ + docker stack deploy --compose-file docker-compose.yaml devops + +
+ +### Setting up Continuous Integration with Jenkins + +1. As the Jenkins user, login to a dockerhub account that has access to the registry: + ++ + sudo su jenkins + docker login +*Enter username and password when requested* + +
+ +2. Expose port 8080 to access Jenkins externally using the command: + ++ + az vm open-port -g devops -n devopsproject --port 8080 --priority 900 + +
+ +3. Access Jenkins site using the public ip address of the virtual machine being used with the addition of :8080 at the end. For example: + +4. Get password for initial screen in Jenkins using the command: + + ++ + sudo cat /var/lib/jenkins/secrets/initialAdminPassword + +
+ +5. On the customize Jenkins page select the option to Install suggested plugins, and create your username and password. + +6. Set up the pipeline + 1. Create Jenkins pipeline by selecting the new item option. Then name the job and select the pipeline option. + + 2. Then in the general section select the GitHub project option and copy in the URL below. +https://github.com/kryan1622/LAFB.git + + 3. Create webhook by selecting the trigger build remotely option in the Build Triggers section and type in: +DEVOPS + + 4. In the pipeline section, select the "Pipeline Script from SCM" option in "Definition". elect Git in the dropdown menu of SCM and copy in the URL used above into Repository URL. + +To complete the webhook go into the settings option within the GitHub repository. Then select the webhook tab and select + +http://51.144.95.241:8080/job/jobname/build + +Then in the payload URL http://username:password@PublicIP:8080/job/jobname/build?token=TOKEN + + + +## CI pipeline + + +### Overview +The above diagram shows the flow of the continuous integration pipeline. +When a developer makes a change to the application in the source code and pushed to GitHub, the webhook is triggered and the Jenkins pipeline will automatically run. +The pipeline runs the following stages: +#### Build +*Goes through the docker-compose.yaml and rebuilds any images that have been changed* +#### Push +*Pushes changed images to dockerhub* +#### Deploy +*Updates changed containers in the stack without redeploying the entire application or affecting the user experience* + +### Switching Implementations +The client asked for three different unique implementations to be included, these were for the prize generator, number generator and account generator. We have provided these and they can be seemlessly switched out for each other. +The images used are as follows: +#### prize generator +keepkarm/account:v1 + * on creating an account, generates a prize of £50 or £0 with a 25% probability of winning +keepkarm/account:v2 + * on creating an account, generates a prize of £100 or £0 with a 25% probability of winning +#### text generator +keepkarm/text_gen:v1 + * generates a random string of three lowercase letters +keepkarm/text_gen:v2 + * generates a random string of two uppercase letters +#### number generator +keepkarm/num_gen:v1 + * generates a random six digit number +keepkarm/num_gen:v2 + * generates a random eight digit number + +If the bank's developers want to switch out any of these implementations for the other, all they need to do is edit the docker-compose.yaml file and push it up to git hub. They can swap the implementations for any of the services by changing both version number in the image name, and the number in the build args option. It is crucial to note that that **both numbers must match**. +When the new docker-compose.yaml is pushed to GitHub + +## Improvements for the Future +Using a local registry would be helpful if deploying this application continuously. In cases of internet connection failures or dockerhub going down (which is not unlikely), images can still be easily accessed. +We suggest using a registry container to improve redundancy. + + +## Authors + +Aysha Marty and Krystal Ryan + + +## Acknowledgements + +* QA consulting and our fantastic instructors +* The rest of our wonderful cohort on the programme diff --git a/account/.dockerignore b/account/.dockerignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/account/.dockerignore @@ -0,0 +1 @@ +node_modules diff --git a/account/Dockerfile b/account/Dockerfile new file mode 100644 index 0000000..776f97e --- /dev/null +++ b/account/Dockerfile @@ -0,0 +1,9 @@ +FROM node:10 +ARG FILE_VERSION=1 +WORKDIR /usr/src/app +COPY package*.json ./ +RUN npm install +COPY . . +COPY routes/account${FILE_VERSION}.js routes/account.js +EXPOSE 5002 +ENTRYPOINT [ "node", "server.js" ] diff --git a/account/package-lock.json b/account/package-lock.json new file mode 100644 index 0000000..094f960 --- /dev/null +++ b/account/package-lock.json @@ -0,0 +1,670 @@ +{ + "name": "discussion_board_example", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", + "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "requires": { + "lodash": "^4.17.10" + } + }, + "axios": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.0.tgz", + "integrity": "sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ==", + "requires": { + "follow-redirects": "1.5.10", + "is-buffer": "^2.0.2" + } + }, + "bcryptjs": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", + "integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=" + }, + "bluebird": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", + "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + } + }, + "bson": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.1.tgz", + "integrity": "sha512-jCGVYLoYMHDkOsbwJZBCqwMHyH4c+wzgI9hG7Z6SZJRXWr+x58pdIbm2i9a/jFGCkRJqRUr8eoI7lDWa0hTkxg==" + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + }, + "content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "express": { + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz", + "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==", + "requires": { + "accepts": "~1.3.5", + "array-flatten": "1.1.1", + "body-parser": "1.18.3", + "content-disposition": "0.5.2", + "content-type": "~1.0.4", + "cookie": "0.3.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.1.1", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.4", + "qs": "6.5.2", + "range-parser": "~1.2.0", + "safe-buffer": "5.1.2", + "send": "0.16.2", + "serve-static": "1.13.2", + "setprototypeof": "1.1.0", + "statuses": "~1.4.0", + "type-is": "~1.6.16", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "body-parser": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", + "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", + "requires": { + "bytes": "3.0.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "~1.6.3", + "iconv-lite": "0.4.23", + "on-finished": "~2.3.0", + "qs": "6.5.2", + "raw-body": "2.3.3", + "type-is": "~1.6.16" + } + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" + }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "iconv-lite": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "raw-body": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", + "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.3", + "iconv-lite": "0.4.23", + "unpipe": "1.0.0" + } + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" + } + } + }, + "finalhandler": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", + "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "statuses": "~1.4.0", + "unpipe": "~1.0.0" + }, + "dependencies": { + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" + } + } + }, + "follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "requires": { + "debug": "=3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + } + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ipaddr.js": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", + "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==" + }, + "is-buffer": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", + "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==" + }, + "kareem": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.0.tgz", + "integrity": "sha512-6hHxsp9e6zQU8nXsP+02HGWXwTkOEw6IROhF2ZA28cYbUk4eJ6QbtZvdqZOdD9YPKghG3apk5eOCvs+tLl3lRg==" + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "optional": true + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" + }, + "mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" + }, + "mime-types": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "requires": { + "mime-db": "1.40.0" + } + }, + "mongodb": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.2.3.tgz", + "integrity": "sha512-jw8UyPsq4QleZ9z+t/pIVy3L++51vKdaJ2Q/XXeYxk/3cnKioAH8H6f5tkkDivrQL4PUgUOHe9uZzkpRFH1XtQ==", + "requires": { + "mongodb-core": "^3.2.3", + "safe-buffer": "^5.1.2" + } + }, + "mongodb-core": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-3.2.3.tgz", + "integrity": "sha512-UyI0rmvPPkjOJV8XGWa9VCTq7R4hBVipimhnAXeSXnuAPjuTqbyfA5Ec9RcYJ1Hhu+ISnc8bJ1KfGZd4ZkYARQ==", + "requires": { + "bson": "^1.1.1", + "require_optional": "^1.0.1", + "safe-buffer": "^5.1.2", + "saslprep": "^1.0.0" + } + }, + "mongoose": { + "version": "5.5.6", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.5.6.tgz", + "integrity": "sha512-XbCVIQTQgzRAPLc8t8Tw5l/uTzdRV6lDnR7Q8KCsXnaX4D1tEFybtWxesidn4WkrGi67PiIWzu5Lsu7SwKkYug==", + "requires": { + "async": "2.6.1", + "bson": "~1.1.1", + "kareem": "2.3.0", + "mongodb": "3.2.3", + "mongodb-core": "3.2.3", + "mongoose-legacy-pluralize": "1.0.2", + "mpath": "0.6.0", + "mquery": "3.2.0", + "ms": "2.1.1", + "regexp-clone": "0.0.1", + "safe-buffer": "5.1.2", + "sift": "7.0.1", + "sliced": "1.0.1" + }, + "dependencies": { + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + } + } + }, + "mongoose-legacy-pluralize": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz", + "integrity": "sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ==" + }, + "mpath": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.6.0.tgz", + "integrity": "sha512-i75qh79MJ5Xo/sbhxrDrPSEG0H/mr1kcZXJ8dH6URU5jD/knFxCVqVC/gVSW7GIXL/9hHWlT9haLbCXWOll3qw==" + }, + "mquery": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-3.2.0.tgz", + "integrity": "sha512-qPJcdK/yqcbQiKoemAt62Y0BAc0fTEKo1IThodBD+O5meQRJT/2HSe5QpBNwaa4CjskoGrYWsEyjkqgiE0qjhg==", + "requires": { + "bluebird": "3.5.1", + "debug": "3.1.0", + "regexp-clone": "0.0.1", + "safe-buffer": "5.1.2", + "sliced": "1.0.1" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "proxy-addr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", + "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.0" + } + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + }, + "range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "regexp-clone": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-0.0.1.tgz", + "integrity": "sha1-p8LgmJH9vzj7sQ03b7cwA+aKxYk=" + }, + "require_optional": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", + "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", + "requires": { + "resolve-from": "^2.0.0", + "semver": "^5.1.0" + } + }, + "resolve-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "saslprep": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", + "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", + "optional": true, + "requires": { + "sparse-bitfield": "^3.0.3" + } + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" + }, + "send": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", + "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.6.2", + "mime": "1.4.1", + "ms": "2.0.0", + "on-finished": "~2.3.0", + "range-parser": "~1.2.0", + "statuses": "~1.4.0" + }, + "dependencies": { + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" + } + } + }, + "serve-static": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", + "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.2", + "send": "0.16.2" + } + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "sift": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/sift/-/sift-7.0.1.tgz", + "integrity": "sha512-oqD7PMJ+uO6jV9EQCl0LrRw1OwsiPsiFQR5AR30heR+4Dl7jBBbDLnNvWiak20tzZlSE1H7RB30SX/1j/YYT7g==" + }, + "sliced": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", + "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" + }, + "sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", + "optional": true, + "requires": { + "memory-pager": "^1.0.2" + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "validator": { + "version": "10.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-10.11.0.tgz", + "integrity": "sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw==" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + } + } +} diff --git a/account/package.json b/account/package.json new file mode 100644 index 0000000..ea3ce10 --- /dev/null +++ b/account/package.json @@ -0,0 +1,19 @@ +{ + "name": "discussion_board_example", + "version": "1.0.0", + "description": "Samples of the Discussion Board Project", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Matt Hunt", + "license": "ISC", + "dependencies": { + "axios": "^0.19.0", + "bcryptjs": "^2.4.3", + "body-parser": "^1.19.0", + "express": "^4.16.4", + "mongoose": "^5.5.6", + "validator": "^10.11.0" + } +} diff --git a/account/routes/account1.js b/account/routes/account1.js new file mode 100644 index 0000000..c07291b --- /dev/null +++ b/account/routes/account1.js @@ -0,0 +1,71 @@ +const express = require("express"); +const router = express.Router(); +const axios = require('axios'); + +// @route GET account/test +// @desc Tests route +// @access Public +router.get("/test", (req, res) => { + res.json({ + message: "account" + }); +}); + +// @route GET account/all +// @desc Get all accounts +// @access Public + +router.get("/all", (req, res) => { + + axios.get('http://db_connector:5001/account/all') + .then(response => { + +res.send(response.data) + }) + .catch(error => { + console.log(error); + }); + + +}); + +// @route POST account/createaccount +// @desc Create an account +// @access Public +router.post("/createAccount", (req, res) => { + + let prizeDecider = Math.floor(Math.random() * 100); + let prize; + + if (prizeDecider >= 75){ + prize = "£50"; + + axios.get('http://notificationserver:9000/notify').catch(error => { + console.log(error); + }); + + }else{ + prize = "No Prize" + } + + const newAccount = { + firstName: req.body.firstName, + lastName: req.body.lastName, + accountnumber: req.body.accountnumber, + prize: prize + }; + + axios.post('http://db_connector:5001/account/createAccount', newAccount) + .then(response => { + + res.send(response.data); + + }) .catch(error => { + console.log(error); + }); + + + +}); + +module.exports = router; diff --git a/account/routes/account2.js b/account/routes/account2.js new file mode 100644 index 0000000..5e1a0b1 --- /dev/null +++ b/account/routes/account2.js @@ -0,0 +1,71 @@ +const express = require("express"); +const router = express.Router(); +const axios = require('axios'); + +// @route GET account/test +// @desc Tests route +// @access Public +router.get("/test", (req, res) => { + res.json({ + message: "account" + }); +}); + +// @route GET account/all +// @desc Get all accounts +// @access Public + +router.get("/all", (req, res) => { + + axios.get('http://db_connector:5001/account/all') + .then(response => { + +res.send(response.data) + }) + .catch(error => { + console.log(error); + }); + + +}); + +// @route POST account/createaccount +// @desc Create an account +// @access Public +router.post("/createAccount", (req, res) => { + + let prizeDecider = Math.floor(Math.random() * 100); + let prize; + + if (prizeDecider >= 75){ + prize = "£100"; + + axios.get('http://notificationserver:9000/notify').catch(error => { + console.log(error); + }); + + }else{ + prize = "No Prize" + } + + const newAccount = { + firstName: req.body.firstName, + lastName: req.body.lastName, + accountnumber: req.body.accountnumber, + prize: prize + }; + + axios.post('http://db_connector:5001/account/createAccount', newAccount) + .then(response => { + + res.send(response.data); + + }) .catch(error => { + console.log(error); + }); + + + +}); + +module.exports = router; diff --git a/account/server.js b/account/server.js new file mode 100644 index 0000000..03438f0 --- /dev/null +++ b/account/server.js @@ -0,0 +1,15 @@ +const express = require("express"); +const bodyParser = require("body-parser"); + +const account = require("./routes/account"); + +const app = express(); + +app.use(bodyParser.urlencoded({ extended: false })); +app.use(bodyParser.json()); + +app.use("/account", account); + +const port = process.env.PORT || 5002; + +app.listen(port, () => console.log(`server running on port ${port}`)); diff --git a/db_connector/Dockerfile b/db_connector/Dockerfile new file mode 100644 index 0000000..aa341f2 --- /dev/null +++ b/db_connector/Dockerfile @@ -0,0 +1,5 @@ +FROM node:10 +COPY . . +RUN npm install +EXPOSE 5001 +ENTRYPOINT ["node", "server.js"] diff --git a/db_connector/config/keys.js b/db_connector/config/keys.js index e61b6ed..c333c2a 100755 --- a/db_connector/config/keys.js +++ b/db_connector/config/keys.js @@ -1,4 +1,3 @@ module.exports = { - mongoURI: "mongodb://lafb:lafb123@ds165632.mlab.com:63835/accounts" + mongoURI: "mongodb://mongo:27017/account" }; - diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..758c0d6 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,96 @@ + +version: '3.3' +services: + nginx: + image: nginx + depends_on: + - client + - server + volumes: + - type: bind + source: ./nginx.conf + target: /etc/nginx/nginx.conf + ports: + - target: 80 + protocol: tcp + published: 80 + + server: + image: keepkarm/server:latest + build: + context: ./server + dockerfile: Dockerfile + ports: + - "8084:8084" + depends_on: + - account + + client: + image: keepkarm/client:latest + build: + context: ./static_website + dockerfile: Dockerfile + ports: + - "8089:8089" + + notificationserver: + image: keepkarm/notify:latest + build: + context: ./notification_server + dockerfile: Dockerfile + ports: + - "9000:9000" + depends_on: + - account + + text_gen: + image: keepkarm/text_gen:v1 + build: + args: + FILE_VERSION: 1 + context: ./text_gen + dockerfile: Dockerfile + ports: + - "9017:9017" + depends_on: + - server + + num_gen: + image: keepkarm/num_gen:v1 + build: + args: + FILE_VERSION: 1 + context: ./num_gen + dockerfile: Dockerfile + ports: + - "9018:9018" + depends_on: + - server + + account: + image: keepkarm/account:v2 + build: + args: + FILE_VERSION: 2 + context: ./account + dockerfile: Dockerfile + ports: + - "5002:5002" + depends_on: + - db_connector + + db_connector: + image: keepkarm/db_connect:latest + build: + context: ./db_connector + dockerfile: Dockerfile + ports: + - "5001:5001" + depends_on: + - mongo + + mongo: + image: mongo + ports: + - "27017:27017" + diff --git a/installation/docker.sh b/installation/docker.sh new file mode 100644 index 0000000..7c381e7 --- /dev/null +++ b/installation/docker.sh @@ -0,0 +1,13 @@ +#! /bin/bash + +user=$(whoami) + +curl https://get.docker.com | sudo bash +sudo usermod -aG docker $user +sudo systemctl docker start +sudo systemctl docker enable + +sudo curl -L "https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose +sudo chmod +x /usr/local/bin/docker-compose + +echo "Please restart your terminal" \ No newline at end of file diff --git a/installation/jenkins.sh b/installation/jenkins.sh new file mode 100644 index 0000000..29e50c8 --- /dev/null +++ b/installation/jenkins.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +sudo apt update +sudo apt install -y openjdk-8-jdk +sudo apt install -y maven + +wget -q -O - https://pkg.jenkins.io/debian/jenkins.io.key | sudo apt-key add - + +sudo sh -c 'echo deb http://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list' + +sudo apt update +sudo apt install -y jenkins + +sudo usermod -aG docker Jenkins + +sudo chmod 777 /var/lib/jenkins/secrets/initialAdminPassword +sudo cat /var/lib/jenkins/secrets/initialAdminPassword + +echo "Please restart your terminal" \ No newline at end of file diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..98c89e8 --- /dev/null +++ b/nginx.conf @@ -0,0 +1,12 @@ +events {} +http { + server { + listen 80; + location / { + proxy_pass http://client:8089/; + } + location /server/ { + proxy_pass http://server:8084/; + } + } +} diff --git a/notification_server/Dockerfile b/notification_server/Dockerfile new file mode 100644 index 0000000..9b28a84 --- /dev/null +++ b/notification_server/Dockerfile @@ -0,0 +1,4 @@ +FROM python +COPY . . +RUN pip install flask +ENTRYPOINT ["python", "app.py"] diff --git a/num_gen/Dockerfile b/num_gen/Dockerfile new file mode 100644 index 0000000..d19a2de --- /dev/null +++ b/num_gen/Dockerfile @@ -0,0 +1,6 @@ +FROM python +ARG FILE_VERSION=1 +COPY . . +COPY num_gen${FILE_VERSION}.py app.py +RUN pip install flask +ENTRYPOINT ["python", "app.py"] diff --git a/num_gen/num_gen1.py b/num_gen/num_gen1.py new file mode 100644 index 0000000..496dc50 --- /dev/null +++ b/num_gen/num_gen1.py @@ -0,0 +1,11 @@ +from flask import Flask, jsonify, make_response +from random import randint +num_gen = Flask(__name__) + +@num_gen.route('/num_gen/') +def num_gen_method(): + rand = randint(100000,999999) + return str(rand) + +if __name__ == '__main__': + num_gen.run(host='0.0.0.0', port=9018) diff --git a/num_gen/num_gen2.py b/num_gen/num_gen2.py new file mode 100644 index 0000000..1238f6c --- /dev/null +++ b/num_gen/num_gen2.py @@ -0,0 +1,11 @@ +from flask import Flask, jsonify, make_response +from random import randint +num_gen = Flask(__name__) + +@num_gen.route('/num_gen/') +def num_gen_method(): + rand = randint(10000000,99999999) + return str(rand) + +if __name__ == '__main__': + num_gen.run(host='0.0.0.0', port=9018) diff --git a/prize_gen/Dockerfile b/prize_gen/Dockerfile new file mode 100644 index 0000000..40a7f9a --- /dev/null +++ b/prize_gen/Dockerfile @@ -0,0 +1,7 @@ +FROM python +ARG FILE_VERSION=1 +COPY . . +COPY prize_gen${FILE_VERSION}.py app.py +RUN pip install flask +RUN pip install requests +ENTRYPOINT ["python", "app.py"] diff --git a/prize_gen/prize_gen1.py b/prize_gen/prize_gen1.py new file mode 100644 index 0000000..143a618 --- /dev/null +++ b/prize_gen/prize_gen1.py @@ -0,0 +1,20 @@ +from flask import Flask, jsonify, make_response +import random +import requests +from random import randrange +prize_gen = Flask(__name__) + + +@prize_gen.route('/prize_gen/', methods=['GET']) +def reset(prob=25): + prize=50 + percent = random.randrange(100) + if prob > percent: + request.get('http://localhost:9000/notify') + return jsonify({"User has won":prize}) + else: + return "No prize for you" + + +if __name__ == '__main__': + prize_gen.run(host='0.0.0.0', port=5000) diff --git a/prize_gen/prize_gen2.py b/prize_gen/prize_gen2.py new file mode 100644 index 0000000..eeb849a --- /dev/null +++ b/prize_gen/prize_gen2.py @@ -0,0 +1,20 @@ +from flask import Flask, jsonify, make_response +import random +import requests +from random import randrange +prize_gen = Flask(__name__) + + +@prize_gen.route('/prize_gen/', methods=['GET']) +def reset(prob=25): + prize=100 + percent = random.randrange(100) + if prob > percent: + request.get('http://localhost:9000/notify') + return jsonify({"User has won":prize}) + else: + return "No prize for you" + + +if __name__ == '__main__': + prize_gen.run(host='0.0.0.0', port=5000) diff --git a/server/Dockerfile b/server/Dockerfile new file mode 100644 index 0000000..d93626e --- /dev/null +++ b/server/Dockerfile @@ -0,0 +1,8 @@ +FROM maven:latest as maven-build +WORKDIR /build +COPY . . +RUN mvn clean package +FROM java:8 +WORKDIR /opt/website +COPY --from=maven-build /build/target/Spring_Day_Two-0.0.1-SNAPSHOT.jar app.jar +ENTRYPOINT ["/usr/bin/java", "-jar", "app.jar"] diff --git a/server/src/main/resources/application.properties b/server/src/main/resources/application.properties index 9d60327..ebdb869 100644 --- a/server/src/main/resources/application.properties +++ b/server/src/main/resources/application.properties @@ -1,8 +1,9 @@ + spring.main.allow-bean-definition-overriding=true server.port=8084 -url.getAll=http://localhost:5001/account/all -url.textGen= ??? -url.numGen= ??? -url.prize= ??? +url.getAll=http://account:5002/account/all +url.textGen=http://text_gen:9017/text_gen/ +url.numGen=http://num_gen:9018/num_gen/ +url.prize=http://account:5002/account/createAccount diff --git a/static_website/Dockerfile b/static_website/Dockerfile new file mode 100644 index 0000000..2621877 --- /dev/null +++ b/static_website/Dockerfile @@ -0,0 +1,5 @@ +FROM node:10 +COPY . . +RUN npm install +EXPOSE 8089 +ENTRYPOINT ["node", "server.js"] diff --git a/static_website/public/index.html b/static_website/public/index.html index 2c753ca..242159a 100644 --- a/static_website/public/index.html +++ b/static_website/public/index.html @@ -9,13 +9,14 @@