Skip to content

Commit

Permalink
Merge pull request #20 from bcgov/task/openshift-web-build
Browse files Browse the repository at this point in the history
Openshift build & deploy
  • Loading branch information
brettedw authored May 2, 2024
2 parents 8df0c96 + 05c8175 commit 63bdef2
Show file tree
Hide file tree
Showing 9 changed files with 526 additions and 0 deletions.
28 changes: 28 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
ARG DOCKER_IMAGE=instrumentisto/flutter:3.13.9

# To build locally, point to a local base image you've already built (see openshift/wps-api-base)
# e.g. : docker build --build-arg DOCKER_IMAGE=wps-api-base:my-tag .

FROM ${DOCKER_IMAGE} as static

WORKDIR /opt/app-root/fbp-go/

# Copy app files from repo
COPY . /opt/app-root/fbp-go/

RUN flutter pub get

RUN flutter build web --base-href /fbp-go/

# # PHASE 2 - prepare hosting.
# https://catalog.redhat.com/software/containers/ubi8/nginx-122/627245493b950f9f4eb01218?architecture=amd64&image=65cba48e6e4e02d0baaab056&container-tabs=overview
FROM registry.access.redhat.com/ubi8/nginx-122:1-55

# Add application sources
ADD ./openshift/nginx.conf "${NGINX_CONF_PATH}"

# Copy the static content:
COPY --from=static /opt/app-root/fbp-go/build/web .

EXPOSE 3000
CMD nginx -g "daemon off;"
47 changes: 47 additions & 0 deletions openshift/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Flutter web build config

Uses flutter image packaged here: https://hub.docker.com/r/instrumentisto/flutter

## Building

### Apply template to build the base image on Openshift

```bash
oc -n e1e498-tools process -f build.yaml | oc -n e1e498-tools apply -f -
```

### Apply template using a specified branch and version

```bash
oc -n e1e498-tools -p VERSION=some-date -p GIT_BRANCH=my-branch process -f openshift/templates/build.yaml | oc -n e1e498-tools apply -f -
```

### Kick off the build

```bash
oc -n e1e498-tools start-build fbp-go --follow
```

### Deploy

Deploy using bash script with the "Version" of ImageStreamTag and specifying test/prod as a suffix. 'test' deploys to dev, 'prod' deploys to prod

```bash
VERSION="may-2-2024" bash openshift/scripts/oc_deploy.sh test apply
```

### TODO Re-tag for production

Assuming you've built an image tagged for dev, you may now want to tag it for production. Remember to retain
the current prod image in case you want to revert!

You may also want to delete any old tags that are no longer relevant.

```bash
# maybe tag the current production image in case we need to revert
oc -n e1e498-tools tag s3-backup:prod s3-backup:previous-prod
# tag this image with something useful, may todays date
oc -n e1e498-tools tag s3-backup:dev s3-backup:some-sensible-tag-like-the-current-date
# tag it for production
oc -n e1e498-tools tag s3-backup:dev s3-backup:prod
```
72 changes: 72 additions & 0 deletions openshift/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
error_log /dev/stdout info;

events {
worker_connections 1024;
}

http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /dev/stdout;

server {
# listen on port 3000
listen 3000;
root /opt/app-root/src;

gzip on;
# By default, NGINX compresses responses only with MIME type text/html.
gzip_types application/javascript application/json text/css;

# force https.
add_header Content-Security-Policy upgrade-insecure-requests;
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
add_header X-Frame-Options DENY;
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options
add_header X-Content-Type-Options nosniff;
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control
# https://www.zaproxy.org/docs/alerts/10015/
# By default - cache nothing.
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header Pragma "no-cache;";
# # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Pragma
add_header Pragma no-cache;
# https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
# unpkg.com; - leaflet
add_header Content-Security-Policy "default-src 'unsafe-inline' *.googleapis.com *.gov.bc.ca *.gstatic.com unpkg.com; img-src *.gov.bc.ca blob: data: https:; script-src 'unsafe-inline' 'unsafe-eval' *.gov.bc.ca; frame-ancestors 'none'";
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
add_header X-Frame-Options DENY;

location / {
# First attempt to serve request as file, then
# as directory, then fall back to redirecting to index.html
try_files $uri $uri/ $uri.html /index.html;
}

location /health {
access_log off;
return 200 "healthy\n";
}

location /ready {
access_log off;
return 200 "ready\n";
}

# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options
location ~* \.(?:css|js|png|xml|svg|json|txt|html|htm)$ {
add_header X-Content-Type-Options "nosniff";
}

# It's useful to cache some things - so let's create some exceptions.
location ~* \.(?:woff2|png|js|css|svg)$ {
expires 30d;
etag off;
if_modified_since off;
add_header Cache-Control "public, no-transform";
}

}
}
53 changes: 53 additions & 0 deletions openshift/scripts/common/common
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/bin/sh -l
#%
#% OpenShift Common Script
#%
#% To be consumed by a set of OpenShift scripts with a pull request-based pipeline.
#% See individual scripts for more information.
#%

# Specify halt conditions (errors, unsets, non-zero pipes), field separator and verbosity
#
set -euo pipefail
IFS=$'\n\t'
[ ! "${VERBOSE:-}" == "true" ] || set -x

# Receive parameters and source/load environment variables from a file
#
SUFFIX=${1:-}
APPLY=$([ "${2:-}" != "apply" ] || echo true)
source "$(dirname ${0})/common/envars"

# If no parameters have been passed show the help header from this script
#
[ "${#}" -gt 0 ] || {
THIS_FILE="$(dirname ${0})/$(basename ${0})"

# Cat this file, grep #% lines and clean up with sed
cat ${THIS_FILE} |
grep "^#%" |
sed -e "s|^#%||g" |
sed -e "s|\${THIS_FILE}|${THIS_FILE}|g"
exit
}

# Verify login
#
$(oc whoami &>/dev/null) || {
echo -e "\nPlease verify oc login\n"
exit
}

# Echo commands and dry run warnings
#
display_helper() {
set +e
if [ ! "${APPLY}" ]; then
echo -e "\n*** This is a dry run. Use 'apply' to deploy. ***"
fi
echo
for i in $*; do
echo -e "$i\n"
done
set -e
}
11 changes: 11 additions & 0 deletions openshift/scripts/common/envars
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
GIT_URL="${GIT_URL:-$(git remote get-url origin)}"
GIT_BRANCH="${GIT_BRANCH:-$(git describe --all --contains HEAD)}"
APP_NAME="${APP_NAME:-fbp-go}"
PROJ_TOOLS="${PROJ_TOOLS:-e1e498-tools}"
PROJ_DEV="${PROJ_DEV:-e1e498-dev}"
PROJ_PROD="${PROJ_PROD:-e1e498-prod}"
TAG_PROD="${TAG_PROD:-prod}"
PATH_BC="${PATH_BC:-$(dirname ${0})/../templates/build.yaml}"
PATH_DEPLOY="${PATH_DEPLOY:-$(dirname ${0})/../templates/deploy.yaml}"
TEMPLATE_PATH="${TEMPLATE_PATH:-$(dirname ${0})/../templates}"
VANITY_DOMAIN="${VANITY_DOMAIN:-psu.nrs.gov.bc.ca}"
66 changes: 66 additions & 0 deletions openshift/scripts/oc_build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#!/bin/sh -l
#
source "$(dirname ${0})/common/common"

# %
# % OpenShift Build Helper
# %
# % Intended for use with a pull request-based pipeline.
# % Suffixes incl.: pr-###, test and prod.
# %
# % Usage:
# %
# % ${THIS_FILE} [SUFFIX] [apply]
# %
# % Examples:
# %
# % Provide a PR number. Defaults to a dry-run.
# % ${THIS_FILE} pr-0
# %
# % Apply when satisfied.
# % ${THIS_FILE} pr-0 apply
# %
OBJ_NAME="${APP_NAME}-${SUFFIX}"

# Process a template (mostly variable substition)
#​​
OC_PROCESS="oc -n ${PROJ_TOOLS} process -f ${PATH_BC} \
-p SUFFIX=${SUFFIX} \
${DOCKER_FILE:+ "-p DOCKER_FILE=${DOCKER_FILE}"}"

# Apply a template (apply or use --dry-run)

OC_APPLY="oc -n ${PROJ_TOOLS} apply -f -"
[ "${APPLY}" ] || OC_APPLY="${OC_APPLY} --dry-run=client"

# Cancel non complete builds and start a new build (apply or don't run)
#
OC_CANCEL_BUILD="oc -n ${PROJ_TOOLS} cancel-build bc/${OBJ_NAME}"
[ "${APPLY}" ] || OC_CANCEL_BUILD=""
OC_START_BUILD="oc -n ${PROJ_TOOLS} start-build ${OBJ_NAME} --follow=true --wait=true"
[ "${APPLY}" ] || OC_START_BUILD=""

# Execute commands
#
eval "${OC_PROCESS}"
eval "${OC_PROCESS} | ${OC_APPLY}"
eval "${OC_CANCEL_BUILD}"
eval "${OC_START_BUILD}"

if [ "${APPLY}" ]; then
# Get the most recent build version
BUILD_LAST=$(oc -n ${PROJ_TOOLS} get bc/${OBJ_NAME} -o 'jsonpath={.status.lastVersion}')
# Command to get the build result
BUILD_RESULT=$(oc -n ${PROJ_TOOLS} get build/${OBJ_NAME}-${BUILD_LAST} -o 'jsonpath={.status.phase}')

# Make sure that result is a successful completion
if [ "${BUILD_RESULT}" != "Complete" ]; then
echo "Build result: ${BUILD_RESULT}"
echo -e "\n*** Build not complete! ***\n"
exit 1
fi
fi

# Provide oc command instruction
#
display_helper "${OC_PROCESS} | ${OC_APPLY}" "${OC_CANCEL_BUILD}" "${OC_START_BUILD}"
55 changes: 55 additions & 0 deletions openshift/scripts/oc_deploy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/bin/sh -l
#
source "$(dirname ${0})/common/common"

#%
#% OpenShift Deploy Helper
#%
#% Suffixes incl.: test and prod.
#%
#% Usage:
#%
#% ${THIS_FILE} [SUFFIX] [apply]
#%
#% Examples:
#%
#% Provide a suffix. Defaults to a dry-run=client.
#% ${THIS_FILE} test
#%
#% Apply when satisfied.
#% ${THIS_FILE} test apply
#%
#% Override default CPU_REQUEST to 2000 millicores
#% CPU_REQUEST=2000m ${THIS_FILE} pr-0

# Target project override for Dev or Prod deployments
#
PROJ_TARGET="${PROJ_TARGET:-${PROJ_DEV}}"
OBJ_NAME="${APP_NAME}"
SUFFIX=${1:-}

if [[ "${SUFFIX}" == "prod" ]]; then
ROUTE_DOMAIN="${VANITY_DOMAIN}"
PROJ_TARGET="${PROJ_PROD}"
echo "${ROUTE_DOMAIN}"
else
PROJ_TARGET="${PROJ_DEV}"
fi
echo "${PROJ_TARGET}"
# Process a template (mostly variable substition)
#
OC_PROCESS="oc -n ${PROJ_TARGET} process -f ${PATH_DEPLOY} \
-p SUFFIX=${SUFFIX} \
${VERSION:+ "-p VERSION=${VERSION}"} \
${ROUTE_DOMAIN:+ "-p ROUTE_DOMAIN=${ROUTE_DOMAIN}"} \
${PROJ_TOOLS:+ "-p PROJ_TOOLS=${PROJ_TOOLS}"} \
${IMAGE_REGISTRY:+ "-p IMAGE_REGISTRY=${IMAGE_REGISTRY}"} \
${REPLICAS:+ "-p REPLICAS=${REPLICAS}"}"

# Apply a template (apply or use --dry-run=client)
#
OC_APPLY="oc -n ${PROJ_TARGET} apply -f -"
[ "${APPLY}" ] || OC_APPLY="${OC_APPLY} --dry-run=client"

eval "${OC_PROCESS}"
eval "${OC_PROCESS} | ${OC_APPLY}"
Loading

0 comments on commit 63bdef2

Please sign in to comment.