Cloud 9 Make Command Line Appear Again
https://github.com/entmike/hanadev/tree/Part3
Overview
In the third part of this series, I volition encompass creating a basic Vue frontend to consume our backend service that we created in Part 2.
Prerequisites
- Cloud 9 fix and configured every bit described in Function 1
- Backend created as described in Part 2
Update the .env file
In part 2, we made utilize of theSYSTEM user to perform a quick test of our backend app. In a existent world utilize instance, we of course do not want to do this. So nosotros volition designate some new environment variables to specify a new application user and password.
HXE_MASTER_PASSWORD=HXEHana1 HANA_APP_UID=APPUSER HANA_APP_PWD=SomeSecretPassword HANA_SERVER=hxehost:39017 HANA_APP_BACKEND=/backend
Update the docker-compose.yaml file
Open up thedocker-etch.yaml file nether/hanadev and update the contents every bit follows:
version: 'ii' services: hello-earth-app: build: context: . dockerfile: ./howdy-earth-app/Dockerfile ports: - "3333:9999" environment: - HANA_UID=${HANA_APP_UID} - HANA_PWD=${HANA_APP_PWD} - HANA_SERVERNODE=${HANA_SERVER} sqlpad: prototype: sqlpad/sqlpad volumes: - sqlpad: /var/lib/sqlpad ports: - "8899:3000" hxehost: image: store/saplabs/hanaexpress:2.00.036.00.20190223.1 hostname: hxe volumes: - hana-express: /hana/mounts command: --hold-to-sap-license --master-countersign ${HXE_MASTER_PASSWORD} volumes: hana-express: sqlpad: Basically, we've only changed thehello-world-app surroundings variable mapping ofHANA_UID andHANA_PWD to point to our newHANA_APP_UID andHANA_APP_PWDvariables in our.env files.
Create the Application User
- Let's briefly start up our HANA Limited DB and SQLPad past typing the following from the
hanadevdirectory in a final window.docker-etch upwardly - Open up SQLPad from
http://[cloud 9 external IP]:8899and log in with the user you created. Refer to Part i if y'all need a reminder on how to log in. - Create a new SQL statement as follows and clickRun
CREATE USER APPUSER Countersign SomeSecretPassword NO FORCE_FIRST_PASSWORD_CHANGE; - That's it. We can now stop our Stack past pressing
Control + Cin the terminal window that you typeddocker-compose up. - Allow'due south commencement back up our stack one last time and make sure our backend app is now running every bit our new application user. Run
docker-etch-up -dand await almost 60 seconds for HANA Express to get-go up. - Adjacent, type
gyre -X Postal service http://localhost:3333/api/overview | grep user. You should get a one line dorsum of the JSON output similar to beneath:% Full % Received % Xferd Average Speed Fourth dimension Time Fourth dimension Current Dload Upload Total Spent Left Speed 100 1202 100 1202 0 0 52260 0 --:--:-- --:--:-- --:--:-- 52260 "user": "APPUSER"Congratulations! You've successfully modified the backend app to use an awarding user.
Creating a Vue Project
As I mentioned in Office one, it's been a long time since playing in spider web frameworks. While this can exist a fleck of a divisive Holy War topic, for me, I've gotten especially fond of Vue. If yous are more of an Angular or React person, feel free to supplant these steps with your favorite frontend tool and read no farther. If you'd similar to create a super simple Vue app, read on.
- From a final window in Deject 9, type
npm i -g @vue/cli. This will install Vue and the Vue CLI. - Side by side, since I'thou not a big CLI guy, allow'due south start up the GUI for the CLI by typing
vue ui -p 8080from thehanadev/hello-world-appdirectory (important.) One time you see the status in your terminal below, proceed to the adjacent step.ec2-user:~/environment/hanadev (Part3) $ vue ui -p 8080 Starting GUI... Ready on http://localhost:8080 - In the Cloud 9 toolbar, clickPreview ->Preview Running Awarding. A browser window within your Cloud ix IDE should open:
- Click theCreate button and so clickCreate a new project hither.
- ForProject Folder, proper noun it
frontend. ClickNext. - Forpreset, go outDefault preset select and clickCreate Project. Vue CLI will begin to generate the boilerplate projection files nether the
hanadev/howdy-world-app/frontendbinder. Later on a few moments, you should go far at a screen saying "Welcome to your new project!". - On the left border of the page, discover the puzzle piecePlugins icon and click it. And so, click the+ Add plugin button at the top-left.
- We are going to install 2 plugins. A routing plugin and a UI plugin. For the router plugin, in that location should be aAdd vue-router button placed prominently at the top of the plugins folio. Click it, then clickKeep. Then don't forget to clickEnd installation
- Later vue-router finishes installing, search for
vue-cli-plugin-vuetify. Click on the matching search result and click onInstall vie-cli-plugin-vuetify. - Subsequently the installation is complete, click on theTasks icon on the left edge of the page. (Clipboard icon.)
- This page serves as a launching point to run vue-cli tasks that yous tin either opt to use this page to run, or if you are more than of a CLI person, you can run from a last if you then wish. For now though, let's click onserve thenRun task.
- In one case the green checkbox appears, we know that our Vue app is running. Click on theOutput button to monitor the condition of our serve chore. You should run across something similar to the following:
App running at: Local: http://localhost:8081/ Network: http://172.16 .0 .99:8081/ Note that the development build is not optimized. To create a product build, run npm run build. - Since we are running in Deject 9 IDE, the IP address reported back and hostname are not accessible from your browser. You will want to substitute your Cloud nine External IDE here. You also will need to expose port
80xx(whichever one is mentioned in the output) in our Cloud 9 EC2 instance in club to access this application easier. Refer to steps in Part 1 if you do non know how to do this. I'd recommend opening upwardly ports8080through8085as sometimes we may be running more one app at once and information technology will salve you a trip to the EC2 Dashboard later on. - Later noting the
80xxport, navigate tohttp://[your deject 9 external ip]:80xx. - If y'all get back a
Welcome to Your Vue.js Appcongratulations! We are prepare to start coding.
Modifying your Vue Projection
Now that we have created the average Vue Project, we are prepare to make some changes to the application. While I am not a Vue adept, and for sake of brevity, I won't be explaining everything that's going on. There are many, many swell Vue tutorials online that I'd highly advise you look for if you are interested in Vue.
- In your Cloud 9 IDE, locate the
/hanadev/hullo-globe-app/frontendfolder. This is where all your frontend code has at present been generated. Alter/Create the following files. - Create Environment Variable files
-
/hello-earth-app/frontend/.env.production:This file volition be used for our final productin build. TheVUE_APP_HANA_APP_BACKENDvariable tells the frontend app where to upshot backend requests to. For production, we'll handle this with Nginx a bit later on.VUE_APP_HANA_APP_BACKEND=/backend -
/hi-world-app/frontend/.env.development.localNOTE: Be sure to add your Cloud 9 External IP accost in the placeholder beneath. For development, we'll want to hit our running Docker stack running in Cloud ix.VUE_APP_HANA_APP_BACKEND=http://[your cloud 9 external ip]:3333
-
- Alter
/howdy-world-app/frontend/src/main.jsimport Vue from 'vue' import './plugins/vuetify' import App from './App.vue' import router from './router' if(!process.env.VUE_APP_HANA_APP_BACKEND){ alert("VUE_APP_HANA_APP_BACKEND surround variable not ready. Please set your environment and restart this frontend server.") }else{ Vue.config.productionTip = false new Vue({ router, render: h => h(App) }).$mountain('#app') } - Alter/Create
/howdy-world-app/frontend/src/router.jsimport Vue from 'vue' import Router from 'vue-router' import Overview from './views/Overview.vue' Vue.utilise(Router) export default new Router({ routes: [ { path: '/', name: 'Overview', component: Overview } ] }) - Alter
/hello-globe-app/frontend/src/App.vue<template> <v-app dark> <AppNav :systemInformation="results.backend_information"/> <v-content transition="slide-10-transition"> <router-view /> </v-content> </five-app> </template> <script> import AppNav from '@/AppNav'; import axios from 'axios'; export default { name: 'App', components: { AppNav }, data () { return { results: { backend_information : { user : 'dummy' } } }; }, methods : { getData (){ axios.post(procedure.env.VUE_APP_HANA_APP_BACKEND + '/api/overview/',{ }).and then( res=>{ if(res.data){ this.results = res.data; this.systemInformation = res.data.backend_information; // panel.log(this.results); }else{ warning(JSON.stringify(res)); this.results = {}; } }, err=> { warning(JSON.stringify(err.response.data)); }).catch( err=>{ alert(`An fault occured communicating with the backend. ${err}`); }) }, }, mounted(){ this.getData(); } }; </script> - Create
/hello-world-app/frontend/src/AppNav.vue<template> <v-toolbar app color="blue darken-iv" dark> <v-toolbar-championship>{{appTitle}}</v-toolbar-title> <template v-for="(item,index) in items"> <5-btn v-if="typeof particular.link === 'undefined'" :key=index flat :to="'/' + item.title">{{item.title}}</five-btn> <v-btn 5-else :cardinal=alphabetize flat :to="'/' + detail.link">{{item.championship}}</v-btn> </template> <five-spacer /> <v-flake color="primary" label outline text-color="white">{{systemInformation.user}}@{{systemInformation.server}}:{{systemInformation.port}}</v-fleck> </v-toolbar> </template> <script> consign default { name: 'AppNav', props : { systemInformation : Object }, information(){ return{ appTitle: 'HANA Sandbox', drawer: false, items: [ { title: 'Overview',link: '' } ] }; } }; </script> <fashion scoped> </manner> - Delete whatever files (
Most.vue,Habitation.vueetc.) under/hello-globe-app/frontend/src/views - Create
/hello-world-app/frontend/src/views/Overview.vue<template> <div> <five-list two-line> <template v-for="(item,index) in results.M_SYSTEM_OVERVIEW"> <v-list-tile :key="index"> <v-list-tile-content> <v-list-tile-title v-html="item.KEY"> </v-list-tile-championship> <5-list-tile-sub-title v-html="item.VAL"> </v-list-tile-sub-title> </v-list-tile-content> </five-listing-tile> </template> </five-list> </div> </template> <script> import axios from 'axios'; export default { name: 'Overview', information: () => ({ results: [] }), components: {}, methods: { getData(){ axios.post(process.env.VUE_APP_HANA_APP_BACKEND + '/api/overview/',{ }).and then( res=>{ if(res.information){ this.results = res.data; }else{ this.results = {}; } }, err=> { alert(JSON.stringify(err.response.data)); }).catch( err=>{ warning(`An fault occured communicating with the backend. ${err}`); }) } }, mounted(){ this.getData(); } } </script> - The the
Overview.vuefile, we are making use of theaxiosnpm module, and so we volition desire to install this. To exercise and so, open a terminal window in Cloud 9 and cd to yourfrontendfolder. Typenpm i axiosto install it.
Running our Frontend App in Developer Mode
If you are still running thevue-cli UI, you can now terminate it by pressingCommand + C. We will now demonstrate how to run the same serve chore via command line from the terminal.
- Brand one more trip over to your EC2 Panel and expose port
3333. This is our backend port that we'll need our browser to hitting in society to get back data from our HANA Container running in our Stack while running in Developer mode. For "production" use cases, we will not demand this port. - In a last window:If your Docker Compose stack is not already running, outset it now:
cd /hanadev docker-compose upwardly -dNext, let's offset up our frontend app in developer mode.
cd /hanadev/hello-world-app/frontend` npm run serve - Later a few moments, yous should receive the following feedback in your concluding:"`bash Done Compiled successfully in 20991ms 18:59:50App running at:
- Local: http://localhost:8080/
- Network: http://172.16.0.99:8080/
Note that the evolution build is not optimized. To create a production build, run npm run build. "`
- Similar earlier, disregard the internal IP, and replace information technology with your Cloud nine External IP address and navigate to
http://[your cloud ix external ip]:80xxwhere80xxis the port mentioned higher up. - If all has gone well, you should receive a page titled "HANA Sandbox" with your App User shown at the elevation correct, and your HANA Express organization information shown below. If so, congratulations! You've created a frontend app that is consuming your Docker Compose stack's backend service!
Running in this manner allows us to make lawmaking changes to our frontend application live in Cloud 9 without deploying over and over once again, withal at the same time attaching to our Docker Compose stack'southward backend app and HANA Express DB. Pretty cool!
Afterwards celebrating, cease the development fashion task past pressingControl + C.
Wrapping it upwardly in our Container
For Part 3, nosotros'll consider this a "Milestone" and apply this as an opportunity to parcel our frontend application changes into ourdocker-etch.yaml file before we call it a day. We'll need to update a few files to incorporate the frontend app.
- Open up your
Dockerfilelocated under/hanadevUpdate information technology with the following:# Docker Paradigm containing SAP HANA npm package FROM node:8-slim LABEL Maintainer="Your Name <your.proper noun@instance.com>" # Install nginx to handle backend and frontend apps RUN apt-go update && apt-get install -y nginx # Add SAP HANA Client NPM bundle from SAP'south npm repository RUN npm config set @sap:registry https://npm.sap.com && npm i -thousand @sap/hana-client # Set the global NPM path Environs variable ENV NODE_PATH /usr/local/lib/node_modules # Configure nginx and startup Copy ./hello-world-app/server.conf /etc/nginx/conf.d/default.conf # Copy backend Node JS modu COPY /hello-world-app/backend /app/backend # Copy production build of Vue frontend app COPY /hello-world-app/frontend/dist /app/frontend # Copy startup.sh script Re-create ./hello-world-app/startup.sh /app/startup.sh WORKDIR /app CMD ./startup.shWe are calculation 3 new chief items hither:
- Our frontend app's production
distfolder will be copied over to our Docker images's/app/frontendbinder. The productiondistfolder is an optimized and minified version of our frontend Vue app. - Install Nginx and copy some configuration files to do some opposite proxy magic so that nosotros tin just take one single port exposed from our container and to abstruse the underlying architecture away.
- Copy over a
startup.shscript since we'll be launching more than than ane procedure for theCMDline.
- Our frontend app's production
- Create
startup.shin/hanadev/hullo-world-app#!/bin/sh echo "Starting Servers..." mkdir -p /run/nginx rm /etc/nginx/sites-enabled/default echo "Starting nginx..." nginx cd /app/backend echo "Starting backend..." npm run prod - Change permissions to executable for
startup.shfrom a final window
cd /hanadev/hello-world-app chmod +10 startup.sh - Create
server.confin/hanadev/hullo-world-app
"`conf
server { listen 80 default_server; # document root # root /app/frontend/; # Route requsts to /backend/ to Backend npm module location /backend/ { proxy_pass http://localhost:9999/; } } ``` - Build our Vue frontend app to generate the
distfolder.cd /hanadev/how-do-you-do-world-app/frontend npm run buildY'all should get some feedback similar to this:
> frontend@0.one.0 build /dwelling house/ec2-user/environment/hanadev/howdy-world-app/frontend > vue-cli-service build ⠏ Building for production... WARNING Compiled with two warnings 19:16:17 warning entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244 KiB). This can impact web functioning. Entrypoints: app (303 KiB) css/chunk-vendors.bc527eeb.css js/chunk-vendors.2793d0c4.js js/app.02b450ce.js warning webpack performance recommendations: Yous tin limit the size of your bundles by using import() or crave.ensure to lazy load some parts of your awarding. For more info visit https://webpack.js.org/guides/code-splitting/ File Size Gzipped dist/js/chunk-vendors.2793d0c4.js 180.43 KiB threescore.x KiB dist/js/app.02b450ce.js 4.87 KiB 2.03 KiB dist/css/chunk-vendors.bc527eeb.css 118.13 KiB 15.45 KiB Images and other types of assets omitted. DONE Build consummate. The dist directory is ready to be deployed. INFO Bank check out deployment instructions at https://cli.vuejs.org/guide/deployment.html - Update our
docker-compose.yamlfile under/hanadev:version: 'two' services: how-do-you-do-earth-app: build: context: . dockerfile: ./hello-earth-app/Dockerfile ports: # - "3333:9999" No longer needed we are using Nginx # Reroute Nginx listening on Port fourscore over to 8080 which we've already exposed in EC2 - "8080:80" environs: - HANA_UID=${HANA_APP_UID} - HANA_PWD=${HANA_APP_PWD} - HANA_SERVERNODE=${HANA_SERVER} sqlpad: prototype: sqlpad/sqlpad volumes: - sqlpad: /var/lib/sqlpad ports: - "8899:3000" hxehost: prototype: store/saplabs/hanaexpress:two.00.036.00.20190223.1 hostname: hxe volumes: - hana-express: /hana/mounts command: --agree-to-sap-license --master-password ${HXE_MASTER_PASSWORD} volumes: hana-limited: sqlpad:- Basically all that we've washed is removed the backend port (
3333) from being accessible, since our Nginx app inside of our Docker container will be opposite-proxying calls to the npm task running there. For development use cases, yous may wish to leave this in place for when developing live and not hosting inside a container, or amend yet, simply have a split docker compose stack for when you are developing, and mayhap this one that represents "production". - Secondly, we're exposing Nginx that is listening on Port
fourscoreover to Port8080since we've already exposed8080in our EC2 Dashboard, and that will save u.s.a. a trip and another exposed port.
- Basically all that we've washed is removed the backend port (
- Rebuild our docker-etch stack:
cd /hanadev docker-compose buildNote The initial fourth dimension y'all run the build it volition take longer, as we've added in a few new Docker paradigm layers to account for the new Nginx add-on, etc. After 2 minutes or so, yous should become a confirmation that the build has finished successfully:
... Step 7/11 : Re-create /how-do-you-do-globe-app/backend /app/backend ---> c5c3508dc2a2 Step 8/11 : Re-create /hello-world-app/frontend/dist /app/frontend ---> 6ee34d81d8d5 Step 9/11 : Copy ./how-do-you-do-globe-app/startup.sh /app/startup.sh ---> 60f38e70da77 Stride 10/xi : WORKDIR /app ---> Running in e54ee8b3c9c6 Removing intermediate container e54ee8b3c9c6 ---> df3d269e1dff Pace 11/11 : CMD ./startup.sh ---> Running in 594e5016ca51 Removing intermediate container 594e5016ca51 ---> 4abedcaed348 Successfully built 4abedcaed348 Successfully tagged hanadev_hello-world-app:latest
Moment of Truth
We are at present ready to test our new Docker Etch stack.
- From
/hanadev, type:docker-compose up - After well-nigh lx seconds, open a browser tab and visit
http://[your cloud 9 ide external ip]:8080If you see the HANA Sandbox page with your HANA Express organization overview, congratulations! Y'all've successfully containerized your frontend and backend app!
What's Next?
As much every bit I enjoy creating punishing and grueling tutorial blogs, I'grand open up for whatever suggestions or ways to improve subsequent posts. Otherwise, for the side by side Part, we'll add together to this frontend application some additional Vue routes for the frontend app, as well every bit Express backend routes to feed it.
Source: https://blogs.sap.com/2019/05/20/develop-simple-on-hana-express-in-aws-cloud-9-part-3-the-frontend-app/
0 Response to "Cloud 9 Make Command Line Appear Again"
Postar um comentário