Installation

NotifyBC can be installed in 3 ways:

  1. Deploy locally from Source Code
  2. Deploy to Kubernetes
  3. Deploy Docker Container

For the purpose of evaluation, both source code and docker container will do. For production, the recommendation is one of

  • deploying to Kubernetes
  • setting up a load balanced app cluster from source code build, backed by MongoDB.

To setup a development environment in order to contribute to NotifyBC, installing from source code is preferred.

Deploy locally from Source Code

System Requirements

  • Software
  • Services
    • MongoDB with replica set, required for production
    • A standard SMTP server to deliver outgoing email, required for production if email is enabled.
    • A tcp proxy server such as nginx stream proxyopen in new window if list-unsubscribe by email is needed and NotifyBC server cannot expose port 25 to internet
    • A SMS service provider if needs to enable SMS channel. The supported service providers are
      • Twilio (default)
      • Swift
    • Redis v6, required if email or sms throttling is enabled
    • SiteMinder, if needs SiteMinder authentication
    • An OIDC provider, if needs OIDC authentication
  • Network and Permissions
    • Minimum runtime firewall requirements:
      • outbound to your ISP DNS server
      • outbound to any on port 80 and 443 in order to run build scripts and send SMS messages
      • outbound to any on SMTP port 25 if using direct mail; for SMTP relay, outbound to your configured SMTP server and port only
      • inbound to listening port (3000 by default) from other authorized server ips
      • if NotifyBC instance will handle anonymous subscription from client browser, the listening port should be open to internet either directly or indirectly through a reverse proxy; If NotifyBC instance will only handle SiteMinder authenticated webapp requests, the listening port should NOT be open to internet. Instead, it should only open to SiteMinder web agent reverse proxy.
    • If list-unsubscribe by email is needed, then one of the following must be met
      • NotifyBC can bind to port 25 opening to internet
      • a tcp proxy server of which port 25 is open to internet. This proxy server can reach NotifyBC on a tcp port.

Installation

Run following commands

git clone https://github.com/bcgov/NotifyBC.git
cd NotifyBC
npm i && npm run build
npm run start

If successful, you will see following output

...
Server is running at http://0.0.0.0:3000

Now open http://localhost:3000open in new window. The page displays NotifyBC Web Console.

The above commands installs the main version, i.e. main branch tip of NotifyBC GitHub repository. To install a specific version, say v2.1.0, run

 git checkout tags/v2.1.0 -b v2.1.0

after cd NotifyBC. A list of versions can be found hereopen in new window.

install from behind firewall

If you want to install on a server behind firewall which restricts internet connection, you can work around the firewall as long as you have access to a http(s) forward proxy server. Assuming the proxy server is http://my_proxy:8080 which proxies both http and https requests, to use it:

  • For Linux

    export http_proxy=http://my_proxy:8080
    export https_proxy=http://my_proxy:8080
    git config --global url."https://".insteadOf git://
    
  • For Windows

    git config --global http.proxy http://my_proxy:8080
    git config --global url."https://".insteadOf git://
    npm config set proxy http://my_proxy:8080
    

Install Windows Service

After get the app running interactively, if your server is Windows and you want to install the app as a Windows service, run

npm install -g node-windows
npm link node-windows
node windows-service.js

This will create and start service notifyBC. To change service name, modify file windows-service.js before running it. See node-windowsopen in new window for other operations such as uninstalling the service.

Deploy to Kubernetes

NotifyBC provides a container packageopen in new window in GitHub Container Registry and a Helmopen in new window chart to facilitate Deploying to Kubernetes. Azure AKS and OpenShift are the two tested platforms. Other Kubernetes platforms are likely to work subject to customizations. Before deploying to AKS, create an ingress controller open in new window.

The deployment can be initiated from localhost or automated by CI service such as Jenkins. Regardless, at the initiator's side following software needs to be installed:

To install,

  1. Follow your platform's instruction to login to the platform. For AKS, run az login and az aks get-credentials; for OpenShift, run oc login

  2. Run

    git clone https://github.com/bcgov/NotifyBC.git
    cd NotifyBC
    helm install -gf helm/platform-specific/<platform>.yaml helm
    

    replace <platform> with openshift or aks depending on your platform.

    The above commands create following artifacts:

    • 1 stateful set of 3 pods running a MongoDB replicaset
    • 1 stateful set of 3 pods running a Redis sentinel
    • 2 deployments - notify-bc-app and notify-bc-cron
    • 1 HPA - notify-bc-cron
    • 5 services - notify-bc, notify-bc-smtp, mongodb-headless, redis and redis-headless
    • 3 PVCs each for one MongoDB pod
    • 3 service accounts - notify-bc, mongodb and redis
    • a few config maps, most importantly notify-bc
    • a few secrets, most importantly mongodb and redis, containing credentials for Mongodb and Redis respectively
    • On AKS,
      • a notify-bc ingress
    • On OpenShift,
      • 2 routes - notify-bc-web and notify-bc-smtp

To upgrade,

helm upgrade <release-name> -f helm/platform-specific/<platform>.yaml --set mongodb.auth.rootPassword=<mongodb-root-password> --set mongodb.auth.replicaSetKey=<mongodb-replica-set-key> --set mongodb.auth.password=<mongodb-password> helm

replace <release-name> with installed helm release name and <platform> with openshift or aks depending on your platform. MongoDB credentials <mongodb-root-password>, <mongodb-replica-set-key> and <mongodb-password> can be found in secret <release-name>-mongodb. It is recommended to specify mongodb credentials in a file rather than command line. See Customizations below.

To uninstall,

helm uninstall <release-name>

replace <release-name> with installed helm release name.

Customizations

Various customizations can be made to chart. Some are platform dependent. To customize, first create a file with extension .local.yaml. The rest of the document assumes the file is helm/values.local.yaml. Then add customized parameters to the file. See helm/values.yaml and Bitnami MongoDB chart readmeopen in new window for customizable parameters. Parameters in helm/values.local.yaml overrides corresponding ones in helm/values.yaml. In particular, parameters under mongodb of helm/values.local.yaml overrides Bitnami MongoDB chart parameters.

To apply customizations, add -f helm/values.local.yaml to the helm command after -f helm/platform-specific/<platform>.yaml. For example, to install chart with customization on OpenShift,

helm install -gf helm/platform-specific/openshift.yaml -f helm/values.local.yaml helm

to upgrade an existing release with customization on OpenShift,

helm upgrade <release-name> -f helm/platform-specific/openshift.yaml -f helm/values.local.yaml helm

Backup helm/values.local.yaml

Backup helm/values.local.yaml to a private secured SCM is highly recommended, especially for production environment.

Following are some common customizations

  • Update config.local.js in ConfigMap, for example to define httpHost

    # in file helm/values.local.yaml
    configMap:
      config.local.js: |-
        module.exports = {
          httpHost: 'https://myNotifyBC.myOrg.com',
        }
    
  • Set hostname on AKS,

    # in file helm/values.local.yaml
    ingress:
      hosts:
        - host: myNotifyBC.myOrg.com
          paths:
            - path: /
    
  • Use Let's Encrypt on AKSopen in new window. After following the instructions in the link, add following ingress customizations to file helm/values.local.yaml

    # in file helm/values.local.yaml
    ingress:
      annotations:
        cert-manager.io/cluster-issuer: letsencrypt
      tls:
        - secretName: tls-secret
          hosts:
            - notify-bc.local
    
  • Route host names on Openshift are by default auto-generated. To set to fixed values

    # in file helm/values.local.yaml
    route:
      web:
        host: 'myNotifyBC.myOrg.com'
      smtp:
        host: 'smtp.myNotifyBC.myOrg.com'
    
  • Add certificates to OpenShift web route

    # in file helm/values.local.yaml
    route:
      web:
        tls:
          caCertificate: |-
            -----BEGIN CERTIFICATE-----
            ...
            -----END CERTIFICATE-----
          certificate: |-
            -----BEGIN CERTIFICATE-----
            ...
            -----END CERTIFICATE-----
          insecureEdgeTerminationPolicy: Redirect
          key: |-
            -----BEGIN PRIVATE KEY-----
            ...
            -----END PRIVATE KEY-----
    
  • MongoDb

    NotifyBC chart depends on Bitnami MongoDB chartopen in new window for MongoDB database provisioning. All documented parameters are customizable under mongodb. For example, to change architecture to standalone

    # in file helm/values.local.yaml
    mongodb:
      architecture: standalone
    

    To set credentials,

    # in file helm/values.local.yaml
    mongodb:
      auth:
        rootPassword: <secret>
        replicaSetKey: <secret>
        passwords:
          - <secret>
    

    To install a Helm chart, the above credentials can be randomly defined. To upgrade an existing release, they must match what's defined in secret <release-name>-mongodb.

  • Redis

    NotifyBC chart depends on Bitnami Redis chartopen in new window for Redis provisioning. All documented parameters are customizable under redis. For example, to set credential

    # in file helm/values.local.yaml
    redis:
      auth:
        password: <secret>
    

    To install a Helm chart, the above credential can be randomly defined. To upgrade an existing release, It must match what's defined in secret <release-name>-redis.

  • Both Bitnami MongoDB and Redis use Docker Hub for docker registry. Rate limit imposed by Docker Hub can cause runtime problems. If your organization has JFrog artifactory, you can change the registry

# in file helm/values.local.yaml
global:
  imageRegistry: <artifactory.myOrg.com>
  imagePullSecrets:
    - <docker-pull-secret>

The above settings assume you have setup secret <docker-pull-secret> to access <artifactory.myOrg.com>. The secret can be created using kubectlopen in new window.

  • Enable scheduled MongoDB backup CronJob

    # in file helm/values.local.yaml
    cronJob:
      enabled: true
      schedule: '1 0 * * *'
      retentionDays: 7
      timeZone: UTC
      persistence:
        size: 5Gi
    

    where

    • enabled: whether to enable the MongoDB backup CronJob or not; default to false
    • schedule: the Unix crontab schedule; default to '1 0 * * *' which runs daily at 12:01AM
    • retentionDays: how many days the backup is retained; default to 7
    • timeZone: the Unix TZ environment variable; default to UTC
    • persistence size: size of PVC; default to 5Gi

    The CronJob backs up MongoDB to a PVC named after the chart with suffix -cronjob-mongodb-backup and purges backups that are older than retentionDays.

    To facilitate restoration, mount the PVC to MongoDB pod

    # in file helm/values.local.yaml
    mongodb:
      extraVolumes:
        - name: export
          persistentVolumeClaim:
            claimName: <PVC_NAME>
      extraVolumeMounts:
        - name: export
          mountPath: /export
          readOnly: true
    

    Restoration can then be achieved by running in MongoDB pod

    mongorestore -u "$MONGODB_EXTRA_USERNAMES" -p"$MONGODB_EXTRA_PASSWORDS" \
    --uri="mongodb://$K8S_SERVICE_NAME" --db $MONGODB_EXTRA_DATABASES --gzip --drop \
    --archive=/export/<mongodb-backup-YYMMDD-hhmmss.gz>
    
  • NotifyBC image tag defaults to appVersion in file helm/Chart.yaml. To change to latest, i.e. tip of the main branch,

    # in file helm/values.local.yaml
    image:
      tag: latest
    
  • Enable autoscaling for app pod

    # in file helm/values.local.yaml
    autoscaling:
      enabled: true
    

Deploy Docker Container

If you have git and Docker installed, you can run following command to deploy NotifyBC Docker container:

docker run --platform linux/amd64 --rm -dp 3000:3000 ghcr.io/bcgov/notify-bc
# open http://localhost:3000

If successful, similar output is displayed as in source code installation.