diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 92e6d7ab4432fb27f9366b35e2db7ec86efde7ed..a5f2813fa9c8baa159ca3ccee68304c719a0ef79 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,35 +1,26 @@
-image: node:20.18.3
-
 stages:
   - build
   - deploy
 
+include:
+  - template: Workflows/Branch-Pipelines.gitlab-ci.yml
+  - project: 'hive/common-ci-configuration'
+    ref: 19b15e2e0ea83de72ce3552a44ca59ab2201de73
+    file:
+      - '/templates/docker_image_jobs.gitlab-ci.yml'
+      - '/templates/npm_projects.gitlab-ci.yml'
+
 variables:
   GIT_DEPTH: 0
   GIT_STRATEGY: clone
   GIT_SUBMODULE_STRATEGY: recursive
 
-cache:
-  key:
-    files:
-      - pnpm-lock.yaml
-  paths:
-    - node_modules/
-    - .pnpm-store/
-
 default:
   tags:
     - public-runner-docker
 
-.npm_based_job:
-  before_script:
-    - corepack enable
-    - corepack prepare pnpm@10.0.0 --activate
-    - pnpm config set store-dir .pnpm-store
-    - pnpm install --frozen-lockfile
-
 build:
-  extends: .npm_based_job
+  extends: .npm_based_job_base
   stage: build
   script:
     - pnpm build
@@ -39,6 +30,42 @@ build:
     when: always
     expire_in: 1 week
 
+.build_app_image_base:
+  extends: .docker_image_builder_job_template
+  stage: deploy
+
+  needs:
+    - job: build
+      artifacts: true
+
+  variables:
+    GIT_SUBMODULE_STRATEGY: normal
+    GIT_DEPTH: 1
+    IMAGE_TAG: ""
+  script:
+    - echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" "$CI_REGISTRY" --password-stdin
+    - ./scripts/ci-helpers/build_instance.sh --push "$IMAGE_TAG" "$CI_PROJECT_DIR" "$CI_REGISTRY_IMAGE" --progress="plain"
+
+  artifacts:
+    reports:
+      dotenv: app_docker_image_name.env
+
+build_app_image:
+  extends: .build_app_image_base
+
+  variables:
+    IMAGE_TAG: "$CI_COMMIT_SHORT_SHA"
+
+push_protected_app_image:
+  extends: .build_app_image_base
+  stage: deploy
+  variables:
+    IMAGE_TAG: "$CI_COMMIT_REF_NAME"
+  rules:
+    - if: '$CI_COMMIT_REF_PROTECTED == "true"'
+      when: on_success
+    - when: never
+
 pages:
   stage: deploy
   script:
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..d7d170a771fb7e56df14620ca6edb9db1fd1cbbb
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,35 @@
+FROM caddy AS app
+COPY ./dist/ /usr/share/caddy/
+
+
+RUN cat > /etc/caddy/Caddyfile <<EOF
+
+:8080 {
+  root * /usr/share/caddy
+  file_server
+  try_files {path} /
+}
+
+EOF
+
+ARG BUILD_TIME
+ARG GIT_COMMIT_SHA
+ARG GIT_CURRENT_BRANCH
+ARG GIT_LAST_LOG_MESSAGE
+ARG GIT_LAST_COMMITTER
+ARG GIT_LAST_COMMIT_DATE
+
+LABEL org.opencontainers.image.created="$BUILD_TIME"
+LABEL org.opencontainers.image.url="https://hive.io/"
+LABEL org.opencontainers.image.documentation="https://gitlab.syncad.com/hive/wallet-dapp"
+LABEL org.opencontainers.image.source="https://gitlab.syncad.com/hive/wallet-dapp"
+#LABEL org.opencontainers.image.version="${VERSION}"
+LABEL org.opencontainers.image.revision="$GIT_COMMIT_SHA"
+LABEL org.opencontainers.image.licenses="MIT"
+LABEL org.opencontainers.image.ref.name="Metamask dApp providing a bridge to Hive blockchain"
+LABEL org.opencontainers.image.title="Hive Bridge Application Image"
+LABEL org.opencontainers.image.description="Runs Hive Bridge applicaton)"
+LABEL io.hive.image.branch="$GIT_CURRENT_BRANCH"
+LABEL io.hive.image.commit.log_message="$GIT_LAST_LOG_MESSAGE"
+LABEL io.hive.image.commit.author="$GIT_LAST_COMMITTER"
+LABEL io.hive.image.commit.date="$GIT_LAST_COMMIT_DATE"
diff --git a/npm-common-config b/npm-common-config
index 5806284d3c6feb2ce52bdb6077c20a9a578bb643..19b15e2e0ea83de72ce3552a44ca59ab2201de73 160000
--- a/npm-common-config
+++ b/npm-common-config
@@ -1 +1 @@
-Subproject commit 5806284d3c6feb2ce52bdb6077c20a9a578bb643
+Subproject commit 19b15e2e0ea83de72ce3552a44ca59ab2201de73
diff --git a/scripts/ci-helpers/build_instance.sh b/scripts/ci-helpers/build_instance.sh
new file mode 100755
index 0000000000000000000000000000000000000000..7377916ef3ec26ecf4eb04de48fcc20556a77455
--- /dev/null
+++ b/scripts/ci-helpers/build_instance.sh
@@ -0,0 +1,125 @@
+#! /bin/bash
+set -euo pipefail
+
+SCRIPTPATH="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
+SCRIPTSDIR="$SCRIPTPATH/.."
+
+print_help () {
+cat <<-EOF
+  Usage: $0 <image_tag> <src_dir> <registry_url> [OPTION[=VALUE]]...
+
+  Builds docker image containing Hive Bridge application installation, ready to run. To spawn it, just run a container and map port 8080 to the host.
+  OPTIONS:
+      --help|-h|-?      Display this help screen and exit
+      --progress=TYPE   Determines how to display build progress (default: 'auto')
+      --push            Allows to automatically push built image to the registry
+EOF
+}
+
+PROGRESS_DISPLAY=${PROGRESS_DISPLAY:-"auto"}
+IMAGE_OUTPUT="--load"
+
+BUILD_IMAGE_TAG=""
+REGISTRY=""
+SRCROOTDIR=""
+
+while [ $# -gt 0 ]; do
+  case "$1" in
+    --help|-h|-?)
+        print_help
+        exit 0
+        ;;
+    --progress=*)
+      arg="${1#*=}"
+      PROGRESS_DISPLAY="$arg"
+      ;;
+
+    --push)
+      IMAGE_OUTPUT="--push"
+      ;;
+
+    *)
+    if [ -z "$BUILD_IMAGE_TAG" ];
+    then
+        BUILD_IMAGE_TAG="${1}"
+    elif [ -z "$SRCROOTDIR" ];
+    then
+        SRCROOTDIR="${1}"
+    elif [ -z "$REGISTRY" ];
+    then
+        REGISTRY=${1}
+    else
+        echo "ERROR: '$1' is not a valid option/positional argument"
+        echo
+        print_help
+        exit 2
+    fi
+    ;;
+    esac
+    shift
+done
+
+
+_TST_IMGTAG=${BUILD_IMAGE_TAG:?"Missing arg #1 to specify built image tag"}
+_TST_SRCDIR=${SRCROOTDIR:?"Missing arg #2 to specify source directory"}
+_TST_REGISTRY=${REGISTRY:?"Missing arg #3 to specify target container registry"}
+
+# Supplement a registry path by trailing slash (if needed)
+#[[ "${REGISTRY}" != */ ]] && REGISTRY="${REGISTRY}/"
+
+echo "Moving into source root directory: ${SRCROOTDIR}"
+
+pushd "$SRCROOTDIR"
+
+export DOCKER_BUILDKIT=1
+BUILD_TIME="$(date -uIseconds)"
+GIT_COMMIT_SHA="$(git rev-parse HEAD || true)"
+if [ -z "$GIT_COMMIT_SHA" ]; then
+  GIT_COMMIT_SHA="[unknown]"
+fi
+
+GIT_CURRENT_BRANCH="$(git branch --show-current || true)"
+if [ -z "$GIT_CURRENT_BRANCH" ]; then
+  GIT_CURRENT_BRANCH="$(git describe --abbrev=0 --all | sed 's/^.*\///' || true)"
+  if [ -z "$GIT_CURRENT_BRANCH" ]; then
+    GIT_CURRENT_BRANCH="[unknown]"
+  fi
+fi
+
+GIT_LAST_LOG_MESSAGE="$(git log -1 --pretty=%B || true)"
+if [ -z "$GIT_LAST_LOG_MESSAGE" ]; then
+  GIT_LAST_LOG_MESSAGE="[unknown]"
+fi
+
+GIT_LAST_COMMITTER="$(git log -1 --pretty="%an <%ae>" || true)"
+if [ -z "$GIT_LAST_COMMITTER" ]; then
+  GIT_LAST_COMMITTER="[unknown]"
+fi
+
+GIT_LAST_COMMIT_DATE="$(git log -1 --pretty="%aI" || true)"
+if [ -z "$GIT_LAST_COMMIT_DATE" ]; then
+  GIT_LAST_COMMIT_DATE="[unknown]"
+fi
+
+echo -e "\nBuilding base instance image...\n"
+
+docker buildx build --target=app \
+  --progress="$PROGRESS_DISPLAY" \
+  --build-arg BUILD_TIME="$BUILD_TIME" \
+  --build-arg GIT_COMMIT_SHA="$GIT_COMMIT_SHA" \
+  --build-arg GIT_CURRENT_BRANCH="$GIT_CURRENT_BRANCH" \
+  --build-arg GIT_LAST_LOG_MESSAGE="$GIT_LAST_LOG_MESSAGE" \
+  --build-arg GIT_LAST_COMMITTER="$GIT_LAST_COMMITTER" \
+  --build-arg GIT_LAST_COMMIT_DATE="$GIT_LAST_COMMIT_DATE" \
+  --tag "${REGISTRY}:${BUILD_IMAGE_TAG}" \
+  "${IMAGE_OUTPUT}" \
+  --file Dockerfile "$SRCROOTDIR"
+
+echo -e "\nDone!\nBuilding instance image...\n"
+
+echo "APP_IMAGE_NAME=$REGISTRY:$BUILD_IMAGE_TAG" > app_docker_image_name.env
+{
+  echo "APP_IMAGE_VERSION=$BUILD_IMAGE_TAG"
+} >> app_docker_image_name.env
+
+popd
\ No newline at end of file