anchor.diff:  Individual parameters for both can be modified within their respective JSON files;
   please see link:containers.adoc for a full list of what can be modified.
   
  -=== Customized Docker Setup
  -
  -==== Docker
  -
  -You can use your own version of the setup.sql SQL file to customize
  -the initialization of database data and objects when the container and
  -database are created.
  -
  -An example is shown in the $CCPROOT/examples/docker/custom-setup/run.sh script
  -and can be run as follows:
  -
  -....
  -cd $CCPROOT/examples/docker/custom-setup
  -./run.sh
  -....
  -
  -This works by placing a file named, setup.sql, within the /pgconf mounted volume
  -directory.  Portions of the setup.sql file are required for the crunchy container
  -to work, see comments within the sample setup.sql file.
  -
   === pgbouncer
   
  -==== Docker
  -
   The pgbouncer utility can be used to provide a connection pool
  -to PostgreSQL databases.  The crunchy-pgbouncer container also
  -contains logic that lets it perform a failover from a primary
  -to a replica database.
  -
  -To test this failover, you first create a running primary/replica
  -cluster as follows:
  -
  -....
  -cd $CCPROOT/examples/docker/primary-replica
  -./run.sh
  -....
  -
  -An example is shown in the $CCPROOT/examples/docker/pgbouncer/run.sh script
  -and can be run as follows:
  -
  -....
  -cd $CCPROOT/examples/docker/pgbouncer
  -./run.sh
  -....
  +to PostgreSQL databases.
   
   This example configures pgbouncer to provide connection pooling
   for the primary and pg-replica databases.  It also sets the FAILOVER
   environment variable which will cause a failover to be triggered
   if the primary database can not be reached.
   
  -To trigger the failover, stop the primary database:
  -
  -....
  -docker stop primary
  -....
  -
  -At this point, the pgbouncer will notice that the primary is not reachable
  -and touch the trigger file on the configured replica database to start
  +After triggering the failover, pgbouncer will notice that the primary is not reachable
  +and will touch the trigger file on the configured replica database to start
   the failover.  The pgbouncer container will then reconfigure
   pgbouncer to relabel the replica database into the primary database so clients
   to pgbouncer will be able to connect to the primary as before the failover.
   
  -To just log into the database from the pgbouncer connection pool
  -you would enter the following using the password "password":
  +This example is required to run in conjunction with another container, by default the
  +*primary-replica* example.
  +
  +Additionally, the example assumes you have an NFS share path of /mnt/nfsfileshare/.
  +NFS is required to mount the pgbouncer configuration files which are
  +then mounted to /pgconf in the crunchy-pgbouncer container.
  +
  +If you mount a /pgconf volume, crunchy-postgres will look at that directory
  +for postgresql.conf, pg_hba.conf, and setup.sql.  If it finds one of them it
  +will use that file instead of the default files.
  +
  +To shutdown the instance and remove the container for each example, run the following:
  +....
  +./cleanup.sh
  +....
  +
  +==== Docker
  +
  +The pgbouncer example is run as follows:
  +....
  +cd $CCPROOT/examples/docker/pgbouncer
  +./run.sh
  +....
  +
  +To trigger the failover, stop the primary database:
  +....
  +docker stop primary
  +....
  +
  +To log into the database from the pgbouncer connection pool
  +you would enter the following using the default password *password*:
   ....
   psql -h localhost -p 12005 -U testuser primary
   ....
   
   ==== Kubernetes
  -
  -*Note*: This example assumes you have run the primary-replica example prior
  -to this example!
  -
  -This example runs a crunchy-pgbouncer container to look for the
  -primary within a PostgreSQL cluster, if it can not find the primary it
  -will proceed to cause a failover to a replica.  It will also configure
  -a pgbouncer container that sets up a connection pool to the
  -configured primary and replica.
   
   Running the example:
   ....
  
positive.code:  * the /pgdata directory is empty
   * the /backups directory contains a valid postgresql.conf file
  
  === Manual Failover
  
  
  ==== OpenShift
  
  An example of performing a database failover is described
  in the following steps:
  
  * create a primary and replica replication
  ....
  cd $CCPROOT/examples/openshift/primary-replica-dc
  ./run.sh
  ....
  * scale up the number of replicas to 2
  ....
  oc scale rc replica-dc-1 --replicas=2
  ....
  * delete the primary pod
  ....
  oc delete pod primary-dc
  ....
  * exec into a replica and create a trigger file to being
    the recovery process, effectively turning the replica into a primary
  ....
  oc exec -it replica-dc-1-lt5a5
  touch /tmp/pg-failover-trigger
  ....
  * change the label on the replica to primary-dc instead of replica-dc
  ....
  oc edit pod/replica-dc-1-lt5a5
  original line: labels/name: replica-dc
  updated line: labels/name: primary-dc
  ....
  
  * or alternatively:
  
  ....
  oc label --overwrite=true pod replica-dc-1-lt5a5 name=primary-dc
  ....
  
  You can test the failover by creating some data on the primary
  and then test to see if the replicas have the replicated data.
  
  ....
  psql -c 'create table foo (id int)' -U primary -h primary-dc postgres
  psql -c 'table foo' -U primary -h replica-dc postgres
  ....
  
  After a failover, you would most likely want to create a database
  backup and be prepared to recreate your cluster from that backup.
  
  === pgbackrest
  
  
  ==== Kubernetes
  
  Starting in release 1.2.5, the pgbackrest utility has been
  added to the crunchy-postgres container.  See the
  link:backrest.adoc[pgbackrest Documentation] for details
  on how this feature works within the container suite.
  
  Start the example as follows:
  ....
  cd $CCPROOT/examples/kube/backrest
  ./run.sh
  ....
  
  This will create the following in your Kube environment:
  
   * A configMap named backrestconf which contains the pgbackrest.conf file
   * primary-backrest pod with pgbackrest archive enabled. An initial stanza db will be created on initialization
   * primary-backrest service
  
  The crunchy-pvc will be used for /pgdata, and crunchy-pvc2 for the /backrestrepo. Examine the /backrestrepo location to view the archive directory and ensure WAL archiving is working. See link:backrest.adoc[pgbackrest Documentation] for steps to backup and restore using pgbackrest.
  
  
  ==== OpenShift
  
  This example shows how to enable pgbackrest as the archiver
  within the crunchy-postgres container.
  See the link:backrest.adoc[pgbackrest documentation] for details and background.
  
  Start by running the example database container:
  ....
  cd $CCPROOT/examples/openshift/backrest
  ./run.sh
  ....
  
  This will create the following:
  
   * PV/PVC for /pgconf and /backrestrepo volumes
   * primary database pod
   * primary service
  
  The run.sh script copies the pgbackrest.conf configuration file
  to /nfsfileshare/pgconf which is our NFS file path.
  
  The archive files are written to the NFS path of /nfsfileshare/backrestrepo.
  
  The presence of /pgconf/pgbackrest.conf is what is used to
  determine whether pgbackrest will be used as the archive command or not.
  You will need to specify the ARCHIVE_TIMEOUT environment variable
  as well to use this.
  
  After you run the example, you should see archive files
  being written to the /backrestrepo volume (/nfsfileshare/backrestrepo).
  
  You can create a backup using backrest using this command within
  the container:
  ....
  pgbackrest --stanza=db backup --db-path=/pgdata/primary-backrest/ --log-path=/tmp --repo-path=/backrestrepo -conf=/pgconf/pgbackrest.conf
  ....
  
  === Restoring pgbackrest
  
  
  ==== Kubernetes & OpenShift
  
  This assumes you have run the pgbackrest example above. There are two options to choose from when performing a restore, DELTA and FULL. A FULL is the default; a DELTA will only occur if the environment variable DELTA is specified in the restore-job spec. Consult the pgbackrest user guide to determine which is best suited to run.
  
  Steps for FULL restore
  
   * Delete the primary-backrest pod, if still running
   * Empty the PGDATA directory (remove all files)
   * Navigate to the backrest-restore examples directory. Execute the full-restore.sh script.
   * Check the restore logs (db-restore.log) in the /backrestrepo mountpoint for success. You can also view the logs of the completed job pod with kubectl get pod -a
   * Re-create the primary-backrest pod in the backrest examples directory. The database will recover.
  
  Steps for DELTA restore
  
   * Delete the primary-backrest pod, if still running
   * rm postmaster.pid from PGDATA.
   * Navigate to the backrest-restore examples directory. Execute the delta-restore.sh script.
   * Check the restore logs (db-restore.log) in the /backrestrepo mountpoint for success. You can also view the logs of the completed job pod with kubectl get pod -a
   * Re-create the primary-backrest pod in the backrest examples directory. The database will recover only files that have changed from the last backup.
  
  === pgadmin4
  
  ==== Docker
  
  This example, $CCPROOT/examples/docker/pgadmin4, provides a
  container that runs the pgadmin4 web application.
  
  To run this example, run the following:
  
  ....
  cd $CCPROOT/examples/docker/pgadmin4
  ./run.sh
  ....
  
  You should now be able to browse to http://YOURLOCALIP:5050
  and log into the web application using a user ID of *admin@admin.org*
  and password of *password*.  Replace YOURLOCALIP with whatever
  your local IP address happens to be.
  
  ==== Kubernetes
  
  This example deploys the pgadmin4 (beta4) web user interface
  for PostgreSQL.
  
  Start the container as follows:
  ....
  cd $CCPROOT/examples/kube/pgadmin4
  ./run.sh
  ....
  
  This will start a container and service for pgadmin4.  You can browse
  the user interface at http://pgadmin4.default.svc.cluster.local:5050
  
  See the pgadmin4 documentation for more details at http://pgadmin.org
  
  The example uses pgadmin4 configuration files which are mounted
  at an NFS mount point, this NFS data directory is mounted into
  the container and used by the pgadmin4 application to persist
  metadata.
  
  
  ==== OpenShift
  
  This example, examples/openshift/pgadmin4, provides a
  container that runs the pgadmin4 web application.
  
  To run this example, run the following:
  
  ....
  cd $CCPROOT/examples/openshift/pgadmin4
  ./run.sh
  ....
  
  This script creates the *pgadmin4* pod and service, it will
  expose port 5050.
  
  You should now be able to browse to http://pgadmin4.openshift.svc.cluster.local:5050
  and log into the web application using a user ID of *admin@admin.org*
  and password of *password*.  Replace YOURLOCALIP with whatever
  your local IP address happens to be.
  
  === Proxy
  
  ==== Docker
  
  A *crunchy-proxy* example is provided that will run a container that
  is configured to be used with the primary and replica example provided
  in the *primary-replica* example.
  
  You can create the proxy by running:
  ....
  cd $CCPROOT/examples/docker/primary-replica
  ./run.sh
  cd $CCPROOT/examples/docker/crunchy-proxy
  ./run.sh
  ....
  
  This proxy will listen on localhost:12432.  You can access the
  *primary-replica* cluster by:
  ....
  psql -h localhost -p 12432 -U postgres postgres
  ....
  
  See this link for details on the *crunchy-proxy*:
  https://github.com/CrunchyData/crunchy-proxy
  
  You might consider *crunchy-proxy* over pgpool and pgbouncer if
  you need load-balancing and smart SQL routing.
  
  ==== Kubernetes
  
  This example runs a crunchy-proxy pod that creates a special purpose
  proxy to a postgres cluster (primary and replica).
  
  *crunchy-proxy* offers a high performance alternative to
  pgbouncer and pgpool.
  
  The proxy example copies a configuration file to the PV_PATH
  and starts up the *crunchy-proxy* within a Deployment.
  
  If you run the example in minikube, you will need to manually
  copy the crunchy-proxy-config.json file to a file on
  the minikube named */data/config.json*.
  
  The proxy reads the configuration file from a */config* volume
  mount and begins execution.
  
  Start by running the proxy container:
  ....
  cd $CCPROOT/examples/kube/primary-replica
  ./run.sh
  cd $CCPROOT/examples/kube/crunchy-proxy
  ./run.sh
  ....
  
  The proxy will listen on port 5432 as specified in the
  configuration file.  The example creates a Service named
  *crunchy-proxy* that you can use to access the configured
  PostgreSQL backend containers from the *primary-replica* example.
  
  See the following link for more information on the *crunchy-proxy*:
  
  https://github.com/CrunchyData/crunchy-proxy
  
  Test the proxy by running psql commands via the proxy connection:
  ....
  psql -h crunchy-proxy -U postgres postgres
  ....
  
  SQL "reads" will be sent to the PostgreSQL replica database if your
  SQL includes the *crunchy-proxy* read annotation.  SQL statements
  that do not include the read annotation will be sent to the primary
  database container within the PostgreSQL cluster.
  
  ==== OpenShift
  
  This example shows how to use the *crunchy-proxy* to
  act as a smart proxy to a PostgreSQL cluster.  The example
  depends upon the *primary-replica* example being run prior.
  
  *crunchy-proxy* offers a high performance alternative to
  pgbouncer and pgpool.
  
  The proxy example copies a configuration file to the PV_PATH
  and starts up the *crunchy-proxy* within a Deployment.
  
  The proxy reads the configuration file from a */config* volume
  mount and begins execution.
  
  Start by running the proxy container:
  ....
  cd $CCPROOT/examples/openshift/primary-replica
  ./run.sh
  cd $CCPROOT/examples/openshift/crunchy-proxy
  ./run.sh
  ....
  
  The proxy will listen on port 5432 as specified in the
  configuration file.  The example creates a Service named
  *crunchy-proxy* that you can use to access the configured
  PostgreSQL backend containers from the *primary-replica* example.
  
  See the following link for more information on the *crunchy-proxy*:
  
  https://github.com/CrunchyData/crunchy-proxy
  
  Test the proxy by running psql commands via the proxy connection:
  ....
  psql -h crunchy-proxy -U postgres postgres
  ....
  
  SQL "reads" will be sent to the PostgreSQL replica database if your
  SQL includes the *crunchy-proxy* read annotation.  SQL statements
  that do not include the read annotation will be sent to the primary
  database container within the PostgreSQL cluster.
  
  === Openshift Customized Configuration
  
  ==== OpenShift
  
  This example shows how you can use your own customized version of setup.sql
  when creating a postgres database container.
  
  If you mount a /pgconf volume, crunchy-postgres will look at that directory
  for postgresql.conf, pg_hba.conf, and setup.sql.  If it finds one of them it
  will use that file instead of the default files.  Currently, if you specify a postgresql.conf
  file, you also need to specify a pg_hba.conf file.
  
  The example shows how a custom setup.sql file can be used.
  Run it as follows:
  
  ....
  cd $CCPROOT/examples/openshift/custom-config
  ./run.sh
  ....
  
  This will start a database container that will use an NFS mounted /pgconf
  directory that will container the custom setup.sql file found in the example
  directory.
  
  === Openshift Customized Configuration with Synchronous Replica
  
  ==== OpenShift
  
  This example shows how you can use your own customized version of postgresql.conf
  and pg_hba.conf to override the default configuration.  It also specifies
  a synchronous replica in the postgresql.conf and starts it up upon creation.
  
  If you mount a /pgconf volume, crunchy-postgres will look at that directory
  for postgresql.conf, pg_hba.conf, and setup.sql.  If it finds one of them it
  will use that file instead of the default files.  Currently, if you specify a postgresql.conf
  file, you also need to specify a pg_hba.conf file.
  
  Run it as follows:
  
  ....
  cd $CCPROOT/examples/openshift/custom-config-sync
  ./run.sh
  ....
  
  This will start a *csprimary* container that will use the custom
  config files when the database is running.  It will also create
  a synchronous replica named *cssyncreplica*. This replica is then
  connected to the primary via streaming replication.
  
  === Openshift Configmap Database Credentials
  
  ==== OpenShift
  
  This example shows how to use a configmap to store the
  postgresql.conf and pg_hba.conf files to be used when
  overriding the default configuration within the container.
  
  Start by running the database container:
  ....
  cd $CCPROOT/examples/openshift/configmap
  ./run.sh
  ....
  
  The files, pg_hba.conf and postgresql.conf, in the
  example directory are used to create a configmap object
  within OpenShift.  Within the run.sh script, the configmap
  is created, and notice within the configmap.json file
  how the /pgconf mount is related to the configmap.
  
  === pgpool
  
  ==== Docker
  
  A pgpool example is provided that will run a pgpool container that
  is configured to be used with the primary and replica example provided
  in the *primary-replica* example. After running
  those commands to create a primary and replica, you can
  create a pgpool container by running the following example command:
  
  ....
  cd $CCPROOT/examples/docker/primary-replica
  ./run.sh
  cd $CCPROOT/examples/docker/pgpool
  ./run.sh
  ....
  
  Enter the following command to connect to the pgpool that is
  mapped to your local port 12003:
  ....
  psql -h localhost -U testuser -p 12003 userdb
  ....
  
  You will enter the password of *password* when prompted.  At this point
  you can execute both INSERT and SELECT statements on the pgpool connection.
  Pgpool will direct INSERT statements to the primary and SELECT statements
  will be sent round-robin to both primary and replica.
  
  ==== Kubernetes
  
  This example runs a pgpool pod that creates a special purpose
  proxy to a PostgreSQL cluster that contains a primary and a replica
  database.
  
  Running the example:
  ....
  
negative.code: and the test table should be present.  When you recover the entire
  WAL history, resuming the recovery is not necessary to enable writes.
  
  ==== Kubernetes
  
  This example is identical to the OpenShift PITR example; please see below for
  