diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index be73b7688d05b7c6725a0fe8c604941158fb1845..8057fab4fca97805b696adcdfc27330701b03707 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -2,38 +2,148 @@ variables:
   DATA_CONUS_2018A: conus-2018a
   DATA_URL: ${S3_BUCKET}/nshmp_2018a_v1.1-CONUS-hazards-with-preliminary-PGV-fv0.3-1x1.nc
   IMAGE_NAME: ${CODE_REGISTRY_IMAGE}/${CI_PROJECT_NAME}:${ENVIRONMENT}-${CI_COMMIT_SHORT_SHA}
+  JACOCO_HTML_DIR: ${REPORTS_DIR}/jacoco/test/html
+  JUNIT_FILES: build/test-results/test/TEST-*.xml
+  REPORTS_DIR: build/reports
   # TODO: Remove hard coded url
   S3_BUCKET: https://nshmp-netcdf-lp-development-rbucket-1of3d1x45yfd9.s3-us-west-2.amazonaws.com
 
+stages:
+  - build
+  - trigger
+
 # Do not run for merge requests
 workflow:
   rules:
     - if: $CI_COMMIT_TAG
     - if: $CI_COMMIT_BRANCH
 
-include:
-  - project: 'ghsc/nshmp/nshmp-pipeline-templates'
-    ref: 'main'
-    file: 'templates/library.yml'
+####
+# Environment Templates
+####
 
-stages:
-  - init
-  - build
-  - trigger
+##
+# Rule for development environment
+##
+.development-env: &development-env
+  if: >
+    $CI_PROJECT_PATH != $UPSTREAM_PATH
+    || (
+      $CI_PROJECT_PATH == $UPSTREAM_PATH
+      && (
+        $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
+        && $CI_COMMIT_BRANCH != 'production'
+        && $CI_COMMIT_TAG == null
+      )
+    )
+  variables:
+    ENVIRONMENT: development
+
+##
+# Rule for staging environment
+##
+.staging-env: &staging-env
+  if: >
+    $CI_PROJECT_PATH == $UPSTREAM_PATH
+    && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
+  variables:
+    ENVIRONMENT: staging
+
+##
+# Rule for production envrionment
+##
+.production-env: &production-env
+  if: >
+    $CI_PROJECT_PATH == $UPSTREAM_PATH
+    && (
+      $CI_COMMIT_BRANCH == 'production'
+      || ( $CI_COMMIT_TAG && $CI_COMMIT_TAG != '' )
+    )
+  variables:
+    ENVIRONMENT: production
+
+####
+# Docker Templates
+####
+
+##
+# Docker in Docker
+##
+.dind:
+  image: ${DEVOPS_REGISTRY}docker:19.03-git
+  services:
+    - alias: docker
+      name: ${DEVOPS_REGISTRY}docker:19.03-dind
+  variables:
+    DOCKER_DRIVER: overlay2
 
-.gradle:
-  image: ${DEVOPS_REGISTRY}usgs/java:11-jdk
+##
+# Build Docker image and push to registry.
+#
+# Pushes to internal registry for all branches and Docker registry
+# on default upstream and production upstream branches.
+##
+.docker-build:
+  extends:
+    - .dind
+  needs: []
+  rules:
+    - *development-env
+    - *staging-env
+    - *production-env
+  script:
+    - BUILD_ARGS='';
+    - |
+      for arg in ${DOCKER_BUILD_ARGS}; do
+        BUILD_ARGS="${BUILD_ARGS} --build-arg ${arg}";
+      done
+    - |
+      docker build \
+        ${BUILD_ARGS} \
+        --pull \
+        --tag "${CODE_REGISTRY_IMAGE}/${CI_PROJECT_NAME}:${IMAGE_TAG}" \
+        --file "${CI_PROJECT_DIR}/${DOCKERFILE}" \
+        "${CI_PROJECT_DIR}/.";
+    - docker push "${CODE_REGISTRY_IMAGE}/${CI_PROJECT_NAME}:${IMAGE_TAG}";
+    - latest_image_name="${CODE_REGISTRY_IMAGE}/${CI_PROJECT_NAME}:${ENVIRONMENT}-latest";
+    - docker tag "${CODE_REGISTRY_IMAGE}/${CI_PROJECT_NAME}:${IMAGE_TAG}" "${latest_image_name}";
+    - docker push "${latest_image_name}";
+    - if [[
+          ${CI_COMMIT_REF_SLUG} == "${CI_DEFAULT_BRANCH}" ||
+          ${CI_COMMIT_REF_SLUG} == "production" ||
+          -n "${CI_COMMIT_TAG}"
+      ]]; then
+        docker tag "${latest_image_name}" "usgs/${CI_PROJECT_NAME}:${ENVIRONMENT}-latest";
+        docker push "usgs/${CI_PROJECT_NAME}:${ENVIRONMENT}-latest";
+      fi
+    - |
+      printf "
+        --------
+        Image Name - %s:%s
+        --------
+      " "${CI_PROJECT_NAME}" "${IMAGE_TAG}";
   stage: build
   tags:
-    - development
+    - build
+  variables:
+    DOCKERFILE: Dockerfile
+    DOCKER_BUILD_ARGS: |
+      BUILD_IMAGE=${DEVOPS_REGISTRY}usgs/centos:latest
+      FROM_IMAGE=${DEVOPS_REGISTRY}usgs/centos:latest
+    IMAGE_TAG: ${ENVIRONMENT}-${CI_COMMIT_SHORT_SHA}
 
 ####
-# Stage: init
+# Java Templates
 ####
 
-Init:
-  extends:
-    - .gradle-init
+##
+# General Java setup
+##
+.java:
+  image: ${DEVOPS_REGISTRY}usgs/amazoncorretto:11
+  stage: build
+  tags:
+    - development
 
 ####
 # Stage: build
@@ -56,98 +166,48 @@ Build Image 2018:
 
 Build Project:
   extends:
-    - .gradle
-  rules:
-    -
-      changes:
-        - 'src/**/java/**'
-        - 'src/**/resources/**'
-        - '**/*.gradle'
-        - '*gradle*'
-      when: on_success
-    -
-      allow_failure: true
-      when: manual
+    - .java
   script:
     - ./gradlew assemble
-  stage: build
+
+Markdown Lint:
+  extends:
+    - .java
+  script:
+    - ./gradlew markdownlint
 
 Unit Tests:
   artifacts:
     paths:
-      - ${REPORTS_DIR}
+      - ${JACOCO_HTML_DIR}
     reports:
       junit: ${JUNIT_FILES}
   coverage: '/Total.*?([0-9]{1,3})%/'
   extends:
-    - .gradle
-  needs:
-    - Init
-  rules:
-    -
-      changes:
-        - 'src/**/java/**'
-        - 'src/**/resources/**'
-        - '**/*.gradle'
-        - '*gradle*'
-      when: on_success
-    -
-      allow_failure: true
-      when: manual
+    - .java
   script:
     - ./gradlew check
     - cat ${JACOCO_HTML_DIR}/index.html
-  stage: build
-
-Markdown Lint:
-  extends:
-    - .gradle
-  needs:
-    - Init
-  rules:
-    -
-      changes:
-        - '**/*.md'
-        - '.markdownlint*'
-      when: on_success
-    -
-      allow_failure: true
-      when: manual
-  script:
-    - ./gradlew markdownlint;
-  stage: build
 
 YAML Lint:
   extends:
-    - .gradle
-  needs:
-    - Init
-  rules:
-    -
-      changes:
-        - '**/*.yml'
-      when: on_success
-    -
-      allow_failure: true
-      when: manual
+    - .java
   script:
-    - ./gradlew yamllint;
-  stage: build
+    - ./gradlew yamllint
 
 ####
 # Stage: trigger
 ####
 
-Trigger nshmp-webapps:
+Trigger AWS Deployment:
   needs:
     - Build Image 2018
   rules:
     -
-      if: !reference [.development-env, if]
-      variables: !reference [.development-env, variables]
+      <<: *development-env
       when: manual
-    - !reference [.staging-env]
-    - !reference [.production-env]
+    - *staging-env
+    - *production-env
   script:
     - apk add curl
     - |
diff --git a/build.gradle b/build.gradle
index 86f3682a217b6a5eb0e94ca7c2b3252b7ee86b3b..720a85507899f04e5bc4e51c74c53dd89fa38591 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,6 +1,6 @@
 plugins {
   id "application"
-  id "com.diffplug.gradle.spotless" version "${spotlessVersion}"
+  id "com.diffplug.spotless" version "${spotlessVersion}"
   id "com.github.johnrengelman.shadow" version "${shadowVersion}"
   id "com.github.node-gradle.node" version "${nodeVersion}"
   id "com.github.spotbugs" version "${spotbugsVersion}"
diff --git a/gradle.properties b/gradle.properties
index 40e982825a126473d55d9ae97d1e402d80010f23..f25537d7a1adce8c5116da701eb055f10f5eb553 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,14 +1,14 @@
 cdmVersion = 5.1.0
 githooksVersion = 1.2.0
 jacksonVersion = 2.9.0
-junitVersion = 5.5.2
+junitVersion = 5.8.2
 mnVersion = 2.4.1
 netcdfVersion = 5.1.0
 nodeVersion = 3.0.1
-nshmpLibVersion = 0.3.1
-nshmpWsUtilsVersion = 0.1.1
+nshmpLibVersion = 0.8.0
+nshmpWsUtilsVersion = 0.1.2
 shadowVersion = 6.1.0
 slfVersion = 1.7.30
-spotbugsVersion = 4.2.4
-spotlessVersion = 4.1.0
+spotbugsVersion = 4.7.0
+spotlessVersion = 6.0.4
 swaggerVersion = 2.1.7
diff --git a/gradle/node.gradle b/gradle/node.gradle
index 44beda13e6097d2f6027bda70a3bb865ca2b633c..46cbc914c2396f3a53da6e8ff619904245cec20c 100644
--- a/gradle/node.gradle
+++ b/gradle/node.gradle
@@ -46,6 +46,5 @@ task yamllint(type: NpxTask) {
     "**/*.yml",
     "--ignore=.gradle/**",
     "--ignore=node_modules/**",
-    "--ignore=.gitlab-ci.yml"
   ]
 }
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index f3d88b1c2faf2fc91d853cd5d4242b5547257070..e708b1c023ec8b20f512888fe07c5bd3ff77bb8f 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index be52383ef49cdf484098989f96738b3d82d7810d..84d1f85fd658134f7e982ae908fd537188f20bfe 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.1-bin.zip
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
index 2fe81a7d95e4f9ad2c9b2a046707d36ceb3980b3..4f906e0c811fc9e230eb44819f509cd0627f2600 100755
--- a/gradlew
+++ b/gradlew
@@ -82,6 +82,7 @@ esac
 
 CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
 
+
 # Determine the Java command to use to start the JVM.
 if [ -n "$JAVA_HOME" ] ; then
     if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
@@ -129,6 +130,7 @@ fi
 if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
     APP_HOME=`cygpath --path --mixed "$APP_HOME"`
     CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
     JAVACMD=`cygpath --unix "$JAVACMD"`
 
     # We build the pattern for arguments to be converted via cygpath
diff --git a/gradlew.bat b/gradlew.bat
index 24467a141f791695fc1009c78d913b2c849d1412..ac1b06f93825db68fb0c0b5150917f340eaa5d02 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -29,6 +29,9 @@ if "%DIRNAME%" == "" set DIRNAME=.
 set APP_BASE_NAME=%~n0
 set APP_HOME=%DIRNAME%
 
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
 @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
 set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
 
@@ -37,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
 
 set JAVA_EXE=java.exe
 %JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto init
+if "%ERRORLEVEL%" == "0" goto execute
 
 echo.
 echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -51,7 +54,7 @@ goto fail
 set JAVA_HOME=%JAVA_HOME:"=%
 set JAVA_EXE=%JAVA_HOME%/bin/java.exe
 
-if exist "%JAVA_EXE%" goto init
+if exist "%JAVA_EXE%" goto execute
 
 echo.
 echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@@ -61,28 +64,14 @@ echo location of your Java installation.
 
 goto fail
 
-:init
-@rem Get command-line arguments, handling Windows variants
-
-if not "%OS%" == "Windows_NT" goto win9xME_args
-
-:win9xME_args
-@rem Slurp the command line arguments.
-set CMD_LINE_ARGS=
-set _SKIP=2
-
-:win9xME_args_slurp
-if "x%~1" == "x" goto execute
-
-set CMD_LINE_ARGS=%*
-
 :execute
 @rem Setup the command line
 
 set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
 
+
 @rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
 
 :end
 @rem End local scope for the variables with windows NT shell