This article introduces a Docker Container Image that runs an Oracle JET application from a Git repository and is capable of dynamic reload of that application when the repository contents get updated. The container image sources are on GitHub in repository https://github.com/lucasjellema/docker-oracle-jet-run-live-reload. It has been pushed to Docker Hub as lucasjellema/ojet-run-live-reload:0.1.
The next figure illustrates the contents and working of the container:
The container contains the Oracle JET 5.2 runtime and CLI for building the JET application as well the Node runtime for serving the JET application and nodemon for restart the that Node runtime application server when any sources are changed. The container is run with a GIT repository URL as minimal input; this repository should contain the Oracle JET application (compatible with JET 5 and developed using the Oracle JET CLI). The application is git cloned from the repository. Subsequently, the JET application is built and copied to the Node application that will serve it. Then this Node application is started – serving the JET application at port 3000.
A reload can be requested on port 4500, endpoint /reload. Such a request will force a git pull – refreshing the application sources from the repository. The application is rebuilt and the Node reloader application is refreshed to serve the new version of the JET application.
The next figure illustrates these steps:
I have selected a JET application repository in GitHub at random and ran it with a single command line statement:
docker run --name jet-app -p 3006:3000 -p 4515:4500 -e GITHUB_URL=https://github.com/vijayveluchamy/ojet-exp-manager -e APPLICATION_ROOT_DIRECTORY= -d lucasjellema/ojet-run-live-reload:0.1
In just a few seconds, the application is available and can be accessed in my browser:
Details on the Generic JET Runner and Reloader
In this section I will show the main constituents of the container image. Note that this container is based on the generic Node application runner that was introduced in an earlier article: https://technology.amis.nl/2018/09/22/generic-docker-container-image-for-running-and-live-reloading-a-node-application-based-on-a-github-repo/ .
The container is based on the node:10 image (perhaps a bit heavy handed?). The Oracle JET CLI is installed into it, as is the nodemon utility. The reloader application is added to the container (a simple Node application that received the reload request and or the GitHub WebHook and invokes the gitRefresh script). Scripts are added to run upon startup (startUpScript.sh) and upon reload (gitRefresh.sh).
Dockerfile:
FROM node:10 #copy the Node Reload server - exposed at port 4500 COPY reloader /tmp/reloader COPY jet-on-node /tmp/jet-on-node RUN cd /tmp/reloader && npm install RUN cd /tmp/jet-on-node && npm install EXPOSE 4500 RUN npm install -g nodemon RUN npm install -g @oracle/ojet-cli COPY startUpScript.sh /tmp COPY gitRefresh.sh /tmp CMD ["chmod", "+x", "/tmp/startUpScript.sh"] RUN /bin/bash -c 'chmod +x /tmp/gitRefresh.sh' ENTRYPOINT ["sh", "/tmp/startUpScript.sh"]
The startUpScript that is executed whenever the container is started up – that takes care of the initial cloning of the JET application from the Git(Hub) URL to directory /tmp/app, followed by building the application (ojet build), copying it to the public directory under the /tmp/jet-on-node directory and the serving of that application using nodemon is shown below. The startup script runs the live reloader application in the background – using (echo “start reload”;npm start)&. That final ampersand (&) takes care of running the command in the background. This npm start command runs the server.js file in /tmp/reloader. This server listens at port 4500 for reload requests.
#!/bin/sh CONTAINER_ALREADY_STARTED="CONTAINER_ALREADY_STARTED_PLACEHOLDER" TARGET_DIR=${APPLICATION_ROOT_DIRECTORY-''} if [ ! -e $CONTAINER_ALREADY_STARTED ]; then touch $CONTAINER_ALREADY_STARTED echo "-- First container startup --" # this branch is only executed when the container is first started cd /tmp # prepare the actual JET app from GitHub mkdir app git clone $GITHUB_URL app echo "GIT repo with Oracle JET application was cloned to /tmp/app/${TARGET_DIR}" cd /tmp/app/$TARGET_DIR #install dependencies for the JET application app npm install #build the deployable JET application from the sources ojet build #copy built JET application to /tmp/jet-on-node/public cp -a ./web/. /tmp/jet-on-node/public #start both the reload app (in the background) and (using nodemon) the actual Node app cd /tmp/reloader echo "starting reload app and nodemon" (echo "start reload";npm start; echo "reload app finished") & cd /tmp/jet-on-node; echo "starting nodemon for JET app copied to /tmp/jet-on-node/public"; nodemon --delay 2.5 --watch public else echo "-- Not first container startup --" cd /tmp/reloader (echo "start reload";npm start; echo "reload app finished") & cd /tmp/jet-on-node; echo "starting nodemon for JET app copied to /tmp/jet-on-node/public"; nodemon --delay 2.5 --watch public fi
The gitRefresh script is executed when a reload request is processed. It performs a git pull to refresh the application sources. Next it rebuilds the JET application using the ojet cli. It copies the build product to the /tmp/jet-node/public directory from where the Node application serves the static sources of the JET application.
#!/bin/sh cd /tmp/app git pull #install dependencies for the Node app npm install #rebuild JET application ojet build #copy built JET application to /tmp/jet-on-node/public cp -a ./web/. /tmp/jet-on-node/public
You can build the Docker container image using
docker build -t "ojet-run-live-reload:0.1" .
Once the image is built it can be tagged and pushed – for me using:
docker tag ojet-run-live-reload:0.1 lucasjellema/ojet-run-live-reload:0.1 docker push lucasjellema/ojet-run-live-reload:0.1
I can now leverage the image using:
docker run --name jet-app -p 3020:3000 -p 4510:4500 -e GITHUB_URL=https://github.com/lucasjellema/webshop-portal-soaring-through-the-cloud-native-sequel -e APPLICATION_ROOT_DIRECTORY= -d lucasjellema/ojet-run-live-reload:0.1
which makes the Soaring through the Cloud Webshop Portal available – in this case on Oracle Container Cloud:
Just for kicks I tried to another random JET application from GitHub:
docker run --name jet-app -p 3008:3000 -p 4515:4500 -e GITHUB_URL=https://github.com/gregja/ojetdiscovery -e APPLICATION_ROOT_DIRECTORY= -d lucasjellema/ojet-run-live-reload:0.1
And that worked nicely too.
Resources
My earlier article Oracle JET Web Applications – Automating Build, Package and Deploy (to Application Container Cloud) using a Docker Container on creating a Docker container that can be used to build an Oracle JET application, package it and deploy it to Oracle Application Container Cloud – https://technology.amis.nl/2018/02/26/oracle-jet-web-applications-automating-build-package-and-deploy-to-application-container-cloud-using-a-docker-container/
My article on a generic Docker container that can run and reload any Node application: https://technology.amis.nl/2018/09/22/generic-docker-container-image-for-running-and-live-reloading-a-node-application-based-on-a-github-repo/