diff --git a/README.md b/README.md
new file mode 100644
index 0000000..3662227
--- /dev/null
+++ b/README.md
@@ -0,0 +1,93 @@
+<!--
+COmanage Docker documentation
+
+Portions licensed to the University Corporation for Advanced Internet
+Development, Inc. ("UCAID") under one or more contributor license agreements.
+See the NOTICE file distributed with this work for additional information
+regarding copyright ownership.
+
+UCAID licenses this file to you under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with the
+License. You may obtain a copy of the License at:
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+# COmanage Match Docker
+
+These instructions detail how to 
+build and deploy a Dockerized version of
+[COmanage Match](https://spaces.internet2.edu/display/COmanage/Home), as well as
+other infrastructure commonly deployed with COmanage Match.
+
+Since COmanage Match is a web application that requires a relational database
+and an authentication mechanism such as 
+[Shibboleth](https://www.shibboleth.net/products/service-provider/), 
+[mod\_auth\_openidc](https://github.com/zmartzone/mod_auth_openidc),
+or just simple [Basic Authentication](https://httpd.apache.org/docs/2.4/mod/mod_auth_basic.html),
+this repository includes multiple Dockerfiles to build images that use various
+combinations of tools.
+
+## Evaluate COmanage Match
+
+If you are new to COmanage Match follow [these instructions](docs/evaluation.md) to build
+and run a simple deployment suitable for evaluating COmanage Match. 
+
+## Building Images
+
+The following link to detailed instructions for building each individual image. See the next
+section for links to documentation on how to deploy the images as services.
+
+* [COmanage Match base image](comanage-match-base/README.md)
+* [COmanage Match with Basic Authentication](comanage-match-basic-auth/README.md)
+* [COmanage Shibboleth SP base image](../comanage-shibboleth-sp-base/README.md)
+* [COmanage Match with Shibboleth SP](comanage-match-shibboleth-sp/README.md)
+* [COmanage Match for Internet2 TAP base](comanage-match-internet2-tap-base/README.md)
+* [COmanage Match for Internet2 TAP](comanage-match-internet2-tap/README.md)
+* [PostgreSQL for COmanage Match](comanage-match-postgres/README.md)
+
+## Deploying Images and Running Services
+
+Since COmanage Match requires a relational database
+it is commont that multiple images need to be simultanesouly instantiated
+as containers. Orchestrating multiple containers to create services is easiest using
+tools such as [Docker Compose](https://docs.docker.com/compose/), 
+[Docker Swarm](https://docs.docker.com/engine/swarm/), or 
+[Kubernetes](https://kubernetes.io/).
+
+The images built from Dockerfiles in this repository may be used with any container
+orchestration platform but the documentation demonstrates how to deploy with
+Docker Swarm (the simple evaluation scenario above uses Docker Compose).
+
+The following link to detailed instructions for a number of deployment scenarios.
+
+* [COmanage Match using the Shibboleth SP and PostgreSQL database](docs/shibboleth-sp-postgresql.md)
+
+## All Documentation
+
+### Building Images
+
+* [COmanage Match base image](comanage-match-base/README.md)
+* [COmanage Match with Basic Authentication](comanage-match-basic-auth/README.md)
+* [COmanage Shibboleth SP base image](../comanage-shibboleth-sp-base/README.md)
+* [COmanage Match with Shibboleth SP](comanage-match-shibboleth-sp/README.md)
+* [COmanage Match for Internet2 TAP base](comanage-match-internet2-tap-base/README.md)
+* [COmanage Match for Internet2 TAP](comanage-match-internet2-tap/README.md)
+* [PostgreSQL for COmanage Match](comanage-match-postgres/README.md)
+
+### Deploying Services
+
+* [COmanage Match using the Shibboleth SP and PostgreSQL database](docs/shibboleth-sp-postgresql.md)
+
+### Other
+
+* [COmanage Match Volumes and Data Persistence](docs/volumes-and-data-persistence.md)
+* [Evaluating COmanage Match using Docker](docs/evaluation.md)
+* [Environment Variables Common to All Images](docs/comanage-match-common-environment-variables.md)
+* [Environment Variables Common to Images using Shibboleth SP for Authentication](../docs/comanage-common-shibboleth-environment-variables.md)
diff --git a/comanage-match-base/.dockerignore b/comanage-match-base/.dockerignore
new file mode 100644
index 0000000..b43bf86
--- /dev/null
+++ b/comanage-match-base/.dockerignore
@@ -0,0 +1 @@
+README.md
diff --git a/comanage-match-base/DatabaseConnectivityTestCommand.php b/comanage-match-base/DatabaseConnectivityTestCommand.php
new file mode 100644
index 0000000..8d05c3b
--- /dev/null
+++ b/comanage-match-base/DatabaseConnectivityTestCommand.php
@@ -0,0 +1,82 @@
+<?php
+/**
+ * COmanage Database Connectivity Test Command, shared between Match and Registry
+ *
+ * Portions licensed to the University Corporation for Advanced Internet
+ * Development, Inc. ("UCAID") under one or more contributor license agreements.
+ * See the NOTICE file distributed with this work for additional information
+ * regarding copyright ownership.
+ *
+ * UCAID licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * @link          http://www.internet2.edu/comanage COmanage Project
+ * @package       match
+ * @since         COmanage Common v1.0.0
+ * @license       Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
+ */
+
+/**
+ * THIS FILE SHOULD BE MASTERED IN THE COMMON REPOSITORY.
+ */
+
+declare(strict_types = 1);
+
+namespace App\Command;
+
+use Cake\Console\Arguments;
+use Cake\Console\Command;
+use Cake\Console\ConsoleIo;
+use Cake\Datasource\ConnectionManager;
+
+use Doctrine\DBAL\DriverManager;
+
+class DatabaseConnectivityTestCommand extends Command {
+  /**
+   * Test Connectivity to the Database
+   *
+   * @since  COmanage Match v1.0.0, COmanage Registry v5.0.0
+   * @param  Arguments $args Command Arguments
+   * @param  ConsoleIo $io   Console IO
+   * @throws RuntimeException
+   */
+
+  public function execute(Arguments $args, ConsoleIo $io) {
+    // Use the ConnectionManager to get the database config.
+    $db = ConnectionManager::get('default');
+    
+    // $db is a ConnectionInterface object
+    $cfg = $db->config();
+    
+    $config = new \Doctrine\DBAL\Configuration();
+    
+    $cfargs = [
+      'dbname'   => $cfg['database'],
+      'user'     => $cfg['username'],
+      'password' => $cfg['password'],
+      'host'     => $cfg['host'],
+      'driver'   => ($cfg['driver'] == 'Cake\Database\Driver\Postgres' ? "pdo_pgsql" : "pdo_mysql")
+    ];
+    
+    $conn = DriverManager::getConnection($cfargs, $config);
+
+    try {
+      $conn->query('SELECT NOW()');
+      $io->out("Connected to database");
+      return 0;
+    } 
+    catch(\Exception $e) {
+      $io->out("Unable to connect to database");
+      return 1;
+    }
+  }
+}
diff --git a/comanage-match-base/DatabaseSetupAlreadyCommand.php b/comanage-match-base/DatabaseSetupAlreadyCommand.php
new file mode 100644
index 0000000..f6be8e8
--- /dev/null
+++ b/comanage-match-base/DatabaseSetupAlreadyCommand.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * COmanage Database Setup Already Command, shared between Match and Registry
+ *
+ * Portions licensed to the University Corporation for Advanced Internet
+ * Development, Inc. ("UCAID") under one or more contributor license agreements.
+ * See the NOTICE file distributed with this work for additional information
+ * regarding copyright ownership.
+ *
+ * UCAID licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * @link          http://www.internet2.edu/comanage COmanage Project
+ * @package       match
+ * @since         COmanage Common v1.0.0
+ * @license       Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
+ */
+
+/**
+ * THIS FILE SHOULD BE MASTERED IN THE COMMON REPOSITORY.
+ */
+
+declare(strict_types = 1);
+
+namespace App\Command;
+
+use Cake\Console\Arguments;
+use Cake\Console\Command;
+use Cake\Console\ConsoleIo;
+use Cake\ORM\TableRegistry;
+
+class DatabaseSetupAlreadyCommand extends Command {
+  /**
+   * Test Connectivity to the Database
+   *
+   * @since  COmanage Match v1.0.0, COmanage Registry v5.0.0
+   * @param  Arguments $args Command Arguments
+   * @param  ConsoleIo $io   Console IO
+   * @throws RuntimeException
+   */
+
+  public function execute(Arguments $args, ConsoleIo $io) {
+    $metaTable = TableRegistry::get('Meta');
+
+    try {
+      $metaTable->findById('1')->firstOrFail();
+      $io->out("Match database is setup");
+      return 0;
+    } 
+    catch(\Exception $e) {
+      $io->out("Match database is not setup");
+      return 1;
+    }
+  }
+}
diff --git a/comanage-match-base/Dockerfile b/comanage-match-base/Dockerfile
new file mode 100644
index 0000000..8e31efc
--- /dev/null
+++ b/comanage-match-base/Dockerfile
@@ -0,0 +1,112 @@
+# COmanage Match Dockerfile
+#
+# Portions licensed to the University Corporation for Advanced Internet
+# Development, Inc. ("UCAID") under one or more contributor license agreements.
+# See the NOTICE file distributed with this work for additional information
+# regarding copyright ownership.
+#
+# UCAID licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+FROM php:7.3.5-apache-stretch
+
+# Official PHP image with Apache HTTPD includes
+# --with-openssl
+# --with-mbstring
+# but intl, pdo, pdo_pgsql, pgsql, 
+# extensions must be built.
+RUN apt-get update && apt-get install -y \
+         libicu-dev \
+         libpq-dev \
+         patch \
+         ssl-cert \
+         wget \
+         zlib1g \
+         libpcre3-dev \
+      && docker-php-ext-configure intl \
+      && docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql \
+      && docker-php-ext-install intl pdo pdo_pgsql pgsql \
+      && docker-php-source delete \
+      && apt-get purge -y \
+         libicu-dev \
+         libpq-dev \
+      && apt-get clean
+
+ARG COMANAGE_MATCH_VERSION
+ENV COMANAGE_MATCH_VERSION ${COMANAGE_MATCH_VERSION:-develop}
+LABEL comanage_match_version=${COMANAGE_MATCH_VERSION}
+
+ENV COMANAGE_MATCH_SRC_URL=https://github.internet2.edu/COmanage/match/archive/${COMANAGE_MATCH_VERSION}.tar.gz
+
+ARG COMANAGE_MATCH_DIR
+ENV COMANAGE_MATCH_DIR ${COMANAGE_MATCH_DIR:-/srv/comanage-match}
+LABEL comanage_match_dir=${COMANAGE_MATCH_DIR}
+
+WORKDIR $COMANAGE_MATCH_DIR
+
+RUN mkdir -p ${COMANAGE_MATCH_DIR} \
+      && wget -O comanage.tar.gz ${COMANAGE_MATCH_SRC_URL} \
+      && tar -zxf comanage.tar.gz -C ${COMANAGE_MATCH_DIR} --strip-components=1 \
+      && rm -f comanage.tar.gz \
+      && rm -f ${COMANAGE_MATCH_DIR}/app/tmp \
+      && rm -f ${COMANAGE_MATCH_DIR}/app/logs \
+      && mkdir ${COMANAGE_MATCH_DIR}/app/tmp \
+      && mkdir ${COMANAGE_MATCH_DIR}/app/logs \
+      && chown -R www-data:www-data ${COMANAGE_MATCH_DIR}/app/tmp \
+      && chown -R www-data:www-data ${COMANAGE_MATCH_DIR}/app/logs \
+      && cd /var/www/html \
+      && ln -s ${COMANAGE_MATCH_DIR}/app/webroot match
+
+RUN a2enmod headers \
+      && a2enmod ssl \
+      && a2enmod rewrite \
+      && a2dissite 000-default.conf \
+      && a2disconf other-vhosts-access-log \
+      && cd /etc/apache2 \
+      && ln -s /etc/ssl/certs/ssl-cert-snakeoil.pem cert.pem \
+      && ln -s /etc/ssl/private/ssl-cert-snakeoil.key privkey.pem
+
+COPY apache-include-directory-match /etc/apache2/
+COPY apache-include-virtual-host-port443-base /etc/apache2/
+COPY apache-include-virtual-host-port80-redirect /etc/apache2/
+
+COPY comanage_utils.sh /usr/local/lib/
+COPY comanage_shibboleth_sp_utils.sh /usr/local/lib/
+COPY docker-comanage-match-entrypoint /usr/local/bin/
+
+# Patch to configure console logging. The patch is
+# applied by the entry point script when appropriate.
+#
+# The patch is the output of the command
+#
+# diff -Naur app.php.original app.php > comanage_match_console_logging.patch
+COPY comanage_match_console_logging.patch /usr/local/src/
+
+# Add commands for testing database connectivity and setup status until
+# they are part of Match source.
+COPY DatabaseConnectivityTestCommand.php ${COMANAGE_MATCH_DIR}/app/src/Command/
+COPY DatabaseSetupAlreadyCommand.php ${COMANAGE_MATCH_DIR}/app/src/Command/
+
+VOLUME ${COMANAGE_MATCH_DIR}/local
+
+EXPOSE 80 443
+
+# Allow values for first administrator bootstrapped into the
+# platform to be specified at image build time, in addition to
+# being injected at run time through the entrypoint script.
+ARG COMANAGE_MATCH_ADMIN_USERNAME
+
+# Set simple defaults for first administrator bootstrapped into the
+ENV COMANAGE_MATCH_ADMIN_USERNAME ${COMANAGE_MATCH_ADMIN_USERNAME:-match.admin}
+
+ENTRYPOINT ["docker-comanage-match-entrypoint"]
+
+CMD ["apache2-foreground"]
diff --git a/comanage-match-base/README.md b/comanage-match-base/README.md
new file mode 100644
index 0000000..7b57cf7
--- /dev/null
+++ b/comanage-match-base/README.md
@@ -0,0 +1,62 @@
+<!--
+COmanage Docker documentation
+
+Portions licensed to the University Corporation for Advanced Internet
+Development, Inc. ("UCAID") under one or more contributor license agreements.
+See the NOTICE file distributed with this work for additional information
+regarding copyright ownership.
+
+UCAID licenses this file to you under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with the
+License. You may obtain a copy of the License at:
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+# COmanage Match Base Image
+
+Intended to build a COmanage Match base image
+using the official PHP with Apache image as the foundation.
+
+By itself the image built from this Dockerfile does **not** provide any
+method for authentication and is not suitable for deployment. 
+
+The image built from this Dockerfile is used as the base
+for images that include an authentication mechanism.
+See other documentation in this
+repository for examples on how to build images on this
+one that include authentication methods like Basic Auth,
+Shibboleth SP, and mod\_auth\_openidc.
+
+## Build Arguments
+
+Building the image requires the following build argument:
+
+```
+--build-arg COMANAGE_MATCH_VERSION=<COmanage Match version number>
+```
+
+## Building
+
+```
+docker build \
+    --build-arg COMANAGE_MATCH_VERSION=<COmanage Match version number> \
+    -t comanage-match-base:<tag> .
+```
+
+## Building Example
+
+```
+export COMANAGE_MATCH_VERSION=1.0.0
+export COMANAGE_MATCH_BASE_IMAGE_VERSION=1
+TAG="${COMANAGE_MATCH_VERSION}-${COMANAGE_MATCH_BASE_IMAGE_VERSION}"
+docker build \
+  --build-arg COMANAGE_MATCH_VERSION=${COMANAGE_MATCH_VERSION} \
+  -t comanage-match-base:${TAG} .
+```
diff --git a/comanage-match-base/apache-include-directory-match b/comanage-match-base/apache-include-directory-match
new file mode 100644
index 0000000..3e7a6aa
--- /dev/null
+++ b/comanage-match-base/apache-include-directory-match
@@ -0,0 +1,6 @@
+<Directory /var/www/html/match>
+Options Indexes FollowSymLinks
+DirectoryIndex index.php
+AllowOverride All
+Require all granted
+</Directory>
diff --git a/comanage-match-base/apache-include-virtual-host-port443-base b/comanage-match-base/apache-include-virtual-host-port443-base
new file mode 100644
index 0000000..044b231
--- /dev/null
+++ b/comanage-match-base/apache-include-virtual-host-port443-base
@@ -0,0 +1,14 @@
+ServerName https://${COMANAGE_MATCH_VIRTUAL_HOST_FQDN}:443
+
+DocumentRoot /var/www/html
+
+RedirectMatch ^/$ /match/
+
+LogLevel warn
+
+Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"
+
+SSLEngine on
+SSLProtocol all -SSLv2 -SSLv3
+SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
+SSLHonorCipherOrder on
diff --git a/comanage-match-base/apache-include-virtual-host-port80-redirect b/comanage-match-base/apache-include-virtual-host-port80-redirect
new file mode 100644
index 0000000..f4b5383
--- /dev/null
+++ b/comanage-match-base/apache-include-virtual-host-port80-redirect
@@ -0,0 +1,6 @@
+<VirtualHost *:80>
+ServerName http://${COMANAGE_MATCH_VIRTUAL_HOST_FQDN}:80
+RewriteEngine On
+RewriteCond %{HTTPS} off
+RewriteRule ^ https://%{HTTP_HOST}:443%{REQUEST_URI} [R=302,L,QSA]
+</VirtualHost>
diff --git a/comanage-match-base/comanage_match_console_logging.patch b/comanage-match-base/comanage_match_console_logging.patch
new file mode 100644
index 0000000..c8e59e1
--- /dev/null
+++ b/comanage-match-base/comanage_match_console_logging.patch
@@ -0,0 +1,36 @@
+--- app.php.original	2019-05-18 06:27:49.677219272 -0500
++++ app.php	2019-05-18 06:36:53.873233082 -0500
+@@ -318,27 +318,21 @@
+      */
+     'Log' => [
+         'debug' => [
+-            'className' => 'Cake\Log\Engine\FileLog',
+-            'path' => LOGS,
+-            'file' => 'debug',
+-            'url' => env('LOG_DEBUG_URL', null),
++            'className' => 'Cake\Log\Engine\ConsoleLog',
++            'stream' => '/dev/stdout',
+             'scopes' => false,
+             'levels' => ['notice', 'info', 'debug'],
+         ],
+         'error' => [
+-            'className' => 'Cake\Log\Engine\FileLog',
+-            'path' => LOGS,
+-            'file' => 'error',
+-            'url' => env('LOG_ERROR_URL', null),
++            'className' => 'Cake\Log\Engine\ConsoleLog',
++            'stream' => '/dev/stdout',
+             'scopes' => false,
+             'levels' => ['warning', 'error', 'critical', 'alert', 'emergency'],
+         ],
+         // To enable this dedicated query log, you need set your datasource's log flag to true
+         'queries' => [
+-            'className' => 'Cake\Log\Engine\FileLog',
+-            'path' => LOGS,
+-            'file' => 'queries',
+-            'url' => env('LOG_QUERIES_URL', null),
++            'className' => 'Cake\Log\Engine\ConsoleLog',
++            'stream' => '/dev/stdout',
+             'scopes' => ['queriesLog'],
+         ],
+     ],
diff --git a/comanage-match-base/comanage_shibboleth_sp_utils.sh b/comanage-match-base/comanage_shibboleth_sp_utils.sh
new file mode 100755
index 0000000..dd9cacf
--- /dev/null
+++ b/comanage-match-base/comanage_shibboleth_sp_utils.sh
@@ -0,0 +1,317 @@
+#!/bin/bash
+
+# COmanage Registry Shibboleth SP Dockerfile entrypoint
+#
+# Portions licensed to the University Corporation for Advanced Internet
+# Development, Inc. ("UCAID") under one or more contributor license agreements.
+# See the NOTICE file distributed with this work for additional information
+# regarding copyright ownership.
+#
+# UCAID licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+if [ -n "$COMANAGE_DEBUG" ]
+then
+    OUTPUT=/dev/stdout
+else
+    OUTPUT=/dev/null
+fi
+
+##########################################
+# Consume injected environment variables
+# Globals:
+#   See function
+# Arguments:
+#   None
+# Returns:
+#   None
+##########################################
+function comanage_shibboleth_sp_utils::consume_injected_environment() {
+
+    echo "Examining environment variables for Shibboleth SP..." > "$OUTPUT" 
+
+    # Configuration details that may be injected through environment
+    # variables or the contents of files.
+    #
+    # SHIBBOLETH_SP_METADATA_PROVIDER_XML may also be injected in the
+    # same way but because of the presence of special characters in the
+    # XML it is handled differently.
+
+    injectable_config_vars=( 
+        SHIBBOLETH_SP_ENTITY_ID
+        SHIBBOLETH_SP_CERT
+        SHIBBOLETH_SP_PRIVKEY
+        SHIBBOLETH_SP_SIGNING_CERT
+        SHIBBOLETH_SP_SIGNING_PRIVKEY
+        SHIBBOLETH_SP_ENCRYPT_CERT
+        SHIBBOLETH_SP_ENCRYPT_PRIVKEY
+        SHIBBOLETH_SP_SAMLDS_URL
+    )
+
+    # If the file associated with a configuration variable is present then 
+    # read the value from it into the appropriate variable. So for example
+    # if the variable COMANAGE_REGISTRY_DATASOURCE_FILE exists and its
+    # value points to a file on the file system then read the contents
+    # of that file into the variable COMANAGE_REGISTRY_DATASOURCE.
+
+    for config_var in "${injectable_config_vars[@]}"
+    do
+        eval file_name=\$"${config_var}_FILE";
+
+        if [ -e "$file_name" ]; then
+            payload=`cat $file_name`
+            declare "${config_var}"="${payload}"
+        fi
+    done
+
+    echo "Done examining environment variables" > "$OUTPUT"
+}
+
+##########################################
+# Prepare shibboleth2.xml configuration file
+# Globals:
+#   OUTPUT
+#   SHIBBOLETH_SP_ENTITY_ID
+#   SHIBBOLETH_SP_SAMLDS_URL
+#   SHIBBOLETH_SP_METADATA_PROVIDER_XML_FILE
+# Arguments:
+#   None
+# Returns:
+#   None
+##########################################
+function comanage_shibboleth_sp_utils::prepare_shibboleth2xml() {
+    
+    local shib_file
+    local xml_content_file
+    local sed_script_file
+
+    # If no shibboleth2.xml file is present then create one using 
+    # injected information or defaults that are not particularly
+    # useful in a federated context but will allow shibd to start.
+    shib_file='/etc/shibboleth/shibboleth2.xml'
+
+    if [[ ! -e "${shib_file}" ]]; then
+        cp "${shib_file}.template" "${shib_file}" > "${OUTPUT}" 2>&1
+        sed -i -e s@%%SHIBBOLETH_SP_ENTITY_ID%%@"${SHIBBOLETH_SP_ENTITY_ID:-https://comanage.registry/shibboleth}"@ "${shib_file}" > "${OUTPUT}" 2>&1
+        sed -i -e s@%%SHIBBOLETH_SP_SAMLDS_URL%%@"${SHIBBOLETH_SP_SAMLDS_URL:-https://localhost/registry/pages/eds/index}"@ "${shib_file}" > "${OUTPUT}" 2>&1
+
+        # The metadata provider injected input most likely contains special characters
+        # so use a sed script instead of simple substitution on the command line.
+
+        if [[ -n "${SHIBBOLETH_SP_METADATA_PROVIDER_XML_FILE}" ]]; then
+            xml_content_file="${SHIBBOLETH_SP_METADATA_PROVIDER_XML_FILE}"
+        else
+            xml_content_file=`/bin/mktemp`
+            echo "${SHIBBOLETH_SP_METADATA_PROVIDER_XML:-}" > "${xml_content_file}"
+        fi
+
+        sed_script_file=`/bin/mktemp`
+        cat > ${sed_script_file}<<EOF
+/%%SHIBBOLETH_SP_METADATA_PROVIDER_XML%%/ {
+    r ${xml_content_file}
+    d
+}
+EOF
+
+        sed -i -f "${sed_script_file}" "${shib_file}" > "${OUTPUT}" 2>&1
+        
+        chmod 0644 "${shib_file}" > "${OUTPUT}" 2>&1
+
+        rm -f "${xml_content_file}" > "${OUTPUT}" 2>&1
+        rm -f "${sed_script_file}" > "${OUTPUT}" 2>&1
+
+    fi
+}
+
+##########################################
+# Prepare SAML certs and keys
+# Globals:
+#   SHIBBOLETH_SP_CERT
+#   SHIBBOLETH_SP_PRIVKEY
+#   SHIBBOLETH_SP_SIGNING_CERT
+#   SHIBBOLETH_SP_SIGNING_PRIVKEY
+#   SHIBBOLETH_SP_ENCRYPT_CERT
+#   SHIBBOLETH_SP_ENCRYPT_PRIVKEY
+# Arguments:
+#   None
+# Returns:
+#   None
+##########################################
+function comanage_shibboleth_sp_utils::prepare_saml_cert_key() {
+
+    local saml_file
+    local owner
+
+    if [[ -e '/etc/debian_version' ]]; then
+        owner='_shibd'
+    elif [[ -e '/etc/centos-release' ]]; then
+        owner='shibd'
+    fi
+
+    # If defined use configured location of Shibboleth SP SAML certificate and key.
+    saml_file='/etc/shibboleth/sp-cert.pem'
+    if [[ -n "${SHIBBOLETH_SP_CERT}" ]]; then
+        cp "${SHIBBOLETH_SP_CERT}" "${saml_file}"
+        chown "${owner}" "${saml_file}"
+        chmod 0644 "${saml_file}"
+    fi
+
+    saml_file='/etc/shibboleth/sp-key.pem'
+    if [[ -n "${SHIBBOLETH_SP_PRIVKEY}" ]]; then
+        cp "${SHIBBOLETH_SP_PRIVKEY}" "${saml_file}"
+        chown "${owner}" "${saml_file}"
+        chmod 0600 "${saml_file}"
+    fi
+
+    saml_file='/etc/shibboleth/sp-signing-cert.pem'
+    if [[ -n "${SHIBBOLETH_SP_SIGNING_CERT}" ]]; then
+        cp "${SHIBBOLETH_SP_SIGNING_CERT}" "${saml_file}"
+        chown "${owner}" "${saml_file}"
+        chmod 0644 "${saml_file}"
+    fi
+
+    saml_file='/etc/shibboleth/sp-signing-key.pem'
+    if [[ -n "${SHIBBOLETH_SP_SIGNING_PRIVKEY}" ]]; then
+        cp "${SHIBBOLETH_SP_SIGNING_PRIVKEY}" "${saml_file}"
+        chown "${owner}" "${saml_file}"
+        chmod 0600 "${saml_file}"
+    fi
+
+    saml_file='/etc/shibboleth/sp-encrypt-cert.pem'
+    if [[ -n "${SHIBBOLETH_SP_ENCRYPT_CERT}" ]]; then
+        cp "${SHIBBOLETH_SP_ENCRYPT_CERT}" "${saml_file}"
+        chown "${owner}" "${saml_file}"
+        chmod 0644 "${saml_file}"
+    fi
+
+    saml_file='/etc/shibboleth/sp-encrypt-key.pem'
+    if [[ -n "${SHIBBOLETH_SP_ENCRYPT_PRIVKEY}" ]]; then
+        cp "${SHIBBOLETH_SP_ENCRYPT_PRIVKEY}" "${saml_file}"
+        chown "${owner}" "${saml_file}"
+        chmod 0600 "${saml_file}"
+    fi
+}
+
+##########################################
+# Manage UID and GID on files
+# Globals:
+#   None
+# Arguments:
+#   None
+# Returns:
+#   None
+##########################################
+function comanage_shibboleth_sp_utils::manage_uid_gid() {
+
+    local owner
+    local ownership
+    local not_readable
+
+    # A deployer may make their own mapping between the shibd username
+    # and the UID, and between the shibd group and GID, so before starting 
+    # make sure files have the correct ownership and group. 
+
+    not_readable='/tmp/shibd-not-readable'
+
+    if [[ -e '/etc/debian_version' ]]; then
+        owner='_shibd'
+        ownership="${owner}:${owner}"
+
+        chown "${ownership}" /etc/shibboleth/sp-cert.pem > /dev/null 2>&1
+        chown "${ownership}" /etc/shibboleth/sp-key.pem > /dev/null 2>&1
+
+        chown "${ownership}" /etc/shibboleth/sp-signing-cert.pem > /dev/null 2>&1
+        chown "${ownership}" /etc/shibboleth/sp-signing-key.pem > /dev/null 2>&1
+
+        chown "${ownership}" /etc/shibboleth/sp-encrypt-cert.pem > /dev/null 2>&1
+        chown "${ownership}" /etc/shibboleth/sp-encrypt-key.pem > /dev/null 2>&1
+
+        chown "${ownership}" /opt/shibboleth-sp/var > /dev/null 2>&1
+        chown "${ownership}" /opt/shibboleth-sp/var > /dev/null 2>&1
+        chown "${ownership}" /opt/shibboleth-sp/var/run > /dev/null 2>&1
+        chown "${ownership}" /opt/shibboleth-sp/var/run/shibboleth > /dev/null 2>&1
+        chown "${ownership}" /opt/shibboleth-sp/var/run/shibboleth/shibd.sock > /dev/null 2>&1
+        chown "${ownership}" /opt/shibboleth-sp/var/log > /dev/null 2>&1
+        chown "${ownership}" /opt/shibboleth-sp/var/log/shibboleth > /dev/null 2>&1
+        chown "${ownership}" /opt/shibboleth-sp/var/log/shibboleth/transaction.log > /dev/null 2>&1
+        chown "${ownership}" /opt/shibboleth-sp/var/log/shibboleth/signature.log > /dev/null 2>&1
+        chown "${ownership}" /opt/shibboleth-sp/var/log/shibboleth/shibd_warn.log > /dev/null 2>&1
+        chown "${ownership}" /opt/shibboleth-sp/var/log/shibboleth/shibd.log > /dev/null 2>&1
+        chown "${ownership}" /opt/shibboleth-sp/var/log/shibboleth-www > /dev/null 2>&1
+        chown "${ownership}" /opt/shibboleth-sp/var/cache > /dev/null 2>&1
+        chown "${ownership}" /opt/shibboleth-sp/var/cache/shibboleth > /dev/null 2>&1
+    elif [[ -e '/etc/centos-release' ]]; then
+        owner='shibd'
+        ownership="${owner}:${owner}"
+
+        chown "${ownership}" /etc/shibboleth/sp-cert.pem > /dev/null 2>&1
+        chown "${ownership}" /etc/shibboleth/sp-key.pem > /dev/null 2>&1
+
+        chown "${ownership}" /etc/shibboleth/sp-signing-cert.pem > /dev/null 2>&1
+        chown "${ownership}" /etc/shibboleth/sp-signing-key.pem > /dev/null 2>&1
+
+        chown "${ownership}" /etc/shibboleth/sp-encrypt-cert.pem > /dev/null 2>&1
+        chown "${ownership}" /etc/shibboleth/sp-encrypt-key.pem > /dev/null 2>&1
+    fi
+
+    # Warn about any files the shibd user cannot read.
+    sudo -u "${owner}" find /etc/shibboleth ! -readable > "${not_readable}" 2>/dev/null
+    if [[ -s "${not_readable}" ]]; then
+        echo "WARNING: the following files are not readable by ${owner}"
+        cat "${not_readable}"
+        echo ""
+    fi
+
+    rm -f "${not_readable}" > /dev/null 2>&1
+}
+
+##########################################
+# Exec to start and become Shibboleth SP shibd
+# Globals:
+#   None
+# Arguments:
+#   Command and arguments to exec
+# Returns:
+#   Does not return
+##########################################
+function comanage_shibboleth_sp_utils::exec_shibboleth_sp_daemon() {
+
+    local user
+    local group
+    local shibd_daemon
+    local config
+    local pidfile
+
+    comanage_shibboleth_sp_utils::consume_injected_environment
+
+    comanage_shibboleth_sp_utils::prepare_shibboleth2xml
+
+    comanage_shibboleth_sp_utils::prepare_saml_cert_key
+
+    comanage_shibboleth_sp_utils::manage_uid_gid
+
+    config='/etc/shibboleth/shibboleth2.xml'
+    pidfile='/var/run/shibboleth/shibd.pid'
+
+    if [[ -e '/etc/debian_version' ]]; then
+        user='_shibd'
+        group='_shibd'
+        shibd_daemon='/opt/shibboleth-sp/sbin/shibd'
+    elif [[ -e '/etc/centos-release' ]]; then
+        user='shibd'
+        group='shibd'
+        shibd_daemon='/usr/sbin/shibd'
+        export LD_LIBRARY_PATH=/opt/shibboleth/lib64
+    fi
+
+    exec "${shibd_daemon}" -f -u "${user}" -g "${group}" -c "${config}" -p "${pidfile}" -F
+}
diff --git a/comanage-match-base/comanage_utils.sh b/comanage-match-base/comanage_utils.sh
new file mode 100644
index 0000000..6aa193c
--- /dev/null
+++ b/comanage-match-base/comanage_utils.sh
@@ -0,0 +1,469 @@
+#!/bin/bash
+
+# COmanage Match bash shell utilities
+#
+# Portions licensed to the University Corporation for Advanced Internet
+# Development, Inc. ("UCAID") under one or more contributor license agreements.
+# See the NOTICE file distributed with this work for additional information
+# regarding copyright ownership.
+#
+# UCAID licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+if [ -n "$COMANAGE_DEBUG" ]
+then
+    OUTPUT=/dev/stdout
+else
+    OUTPUT=/dev/null
+fi
+
+##########################################
+# Configure console (stdout) logging
+# Globals:
+#   COMANAGE_MATCH_DIR
+#   OUTPUT
+# Arguments:
+#   None
+# Returns:
+#   None
+##########################################
+function comanage_utils::configure_console_logging() {
+    pushd "$COMANAGE_MATCH_DIR/app/config" > "$OUTPUT" 2>&1
+    patch < /usr/local/src/comanage_match_console_logging.patch > "$OUTPUT" 2>&1
+    popd > "$OUTPUT" 2>&1
+}
+
+##########################################
+# Configure TIER logging
+# Globals:
+#   ENV
+#   USERTOKEN
+#   OUTPUT
+# Arguments:
+#   NONE
+# Returns:
+#   None
+##########################################
+function comanage_utils::configure_tier_logging() {
+
+    comanage_utils::manage_tier_environment
+
+    # Create pipes to use for COmanage Match instead of standard log files.
+    rm -rf "$COMANAGE_MATCH_DIR/app/logs" > "$OUTPUT" 2>&1
+    mkfifo -m 666 "$COMANAGE_MATCH_DIR/app/logs/error.log" > "$OUTPUT" 2>&1
+    mkfifo -m 666 "$COMANAGE_MATCH_DIR/app/logs/debug.log" > "$OUTPUT" 2>&1
+
+    # Format any output from COmanange Registry into standard TIER form.
+    (cat <> "$COMANAGE_MATCH_DIR/app/logs/error.log" | awk -v ENV="$ENV" -v UT="$USERTOKEN" '{printf "comanage_match;error.log;%s;%s;%s\n", ENV, UT, $0; fflush()}' 1>/tmp/logpipe)&
+    (cat <> "$COMANAGE_MATCH_DIR/app/logs/debug.log" | awk -v ENV="$ENV" -v UT="$USERTOKEN" '{printf "comanage_match;debug.log;%s;%s;%s\n", ENV, UT, $0; fflush()}' 1>/tmp/logpipe)&
+}
+
+##########################################
+# Consume injected environment variables
+# Globals:
+#   See function
+# Arguments:
+#   None
+# Returns:
+#   None
+##########################################
+function comanage_utils::consume_injected_environment() {
+    
+    echo "Examining environment variables..." > "$OUTPUT" 
+
+    # Configuration details that may be injected through environment
+    # variables or the contents of files.
+    local injectable_config_vars
+
+    injectable_config_vars=( 
+        COMANAGE_MATCH_ADMIN_USERNAME
+        COMANAGE_MATCH_DATASOURCE
+        COMANAGE_MATCH_DATABASE
+        COMANAGE_MATCH_DATABASE_HOST
+        COMANAGE_MATCH_DATABASE_USER
+        COMANAGE_MATCH_DATABASE_USER_PASSWORD
+        COMANAGE_MATCH_SECURITY_SALT
+        COMANAGE_MATCH_SECURITY_SEED
+        COMANAGE_MATCH_VIRTUAL_HOST_FQDN
+        HTTPS_CERT_FILE
+        HTTPS_PRIVKEY_FILE
+    )
+
+    # If the file associated with a configuration variable is present then 
+    # read the value from it into the appropriate variable. So for example
+    # if the variable COMANAGE_MATCH_DATASOURCE_FILE exists and its
+    # value points to a file on the file system then read the contents
+    # of that file into the variable COMANAGE_MATCH_DATASOURCE.
+
+    local config_var
+    for config_var in "${injectable_config_vars[@]}"
+    do
+        local file_name
+        eval file_name=\$"${config_var}_FILE";
+
+        if [[ -e "$file_name" ]]; then
+            declare -g "${config_var}"=`cat $file_name`
+            echo "Set ${config_var} to be contents of ${file_name}" > "$OUTPUT"
+        fi
+    done
+
+    echo "Done examining environment variables" > "$OUTPUT"
+}
+
+##########################################
+# Exec to start and become Apache HTTP Server
+# Globals:
+#   None
+# Arguments:
+#   Command and arguments to exec
+# Returns:
+#   Does not return
+##########################################
+function comanage_utils::exec_apache_http_server() {
+
+    comanage_utils::consume_injected_environment
+
+    comanage_utils::configure_console_logging
+
+    comanage_utils::prepare_local_directory
+
+    comanage_utils::prepare_database_config
+
+    comanage_utils::prepare_https_cert_key
+
+    comanage_utils::prepare_server_name
+
+    comanage_utils::wait_database_connectivity
+
+    comanage_utils::match_setup
+
+    comanage_utils::tmp_ownership
+
+    # first arg is `-f` or `--some-option`
+    if [ "${1#-}" != "$1" ]; then
+        set -- apache2-foreground "$@"
+    fi
+
+    exec "$@"
+}
+
+##########################################
+# Manage TIER environment variables
+# Globals:
+#   None
+# Arguments:
+#   None
+# Returns:
+#   None
+##########################################
+function comanage_utils::manage_tier_environment() {
+    
+    # If ENV or USERTOKEN as injected by the deployer contain a semi-colon remove it.
+    if [[ ${ENV} =~ .*";".* ]]; then
+        ENV=`echo ${ENV} | tr -d ';'`
+        export ENV
+    fi
+
+    if [[ ${USERTOKEN} =~ .*";".* ]]; then
+        USERTOKEN=`echo ${USERTOKEN} | tr -d ';'`
+        export USERTOKEN
+    fi
+
+    # If ENV or USERTOKEN as injected by the deployer contain a space remove it.
+    if [[ ${ENV} =~ [[:space:]] ]]; then
+        ENV=`echo ${ENV} | tr -d [:space:]`
+        export ENV
+    fi
+
+    if [[ ${USERTOKEN} =~ [[:space:]] ]]; then
+        USERTOKEN=`echo ${USERTOKEN} | tr -d [:space:]`
+        export USERTOKEN
+    fi
+}
+
+##########################################
+# Prepare database configuration
+# Globals:
+#   COMANAGE_MATCH_DATABASE
+#   COMANAGE_MATCH_DATABASE_HOST
+#   COMANAGE_MATCH_DATABASE_USER
+#   COMANAGE_MATCH_DATABASE_USER_PASSWORD
+#   COMANAGE_MATCH_DATASOURCE
+#   COMANAGE_MATCH_DIR
+#   OUTPUT
+# Arguments:
+#   None
+# Returns:
+#   None
+##########################################
+function comanage_utils::prepare_database_config() {
+
+    # If the COmanage Match database configuration file does not exist
+    # then try to create it from injected information with reasonable defaults
+    # that aid simple evaluation deployments.
+    local database_config
+    database_config="$COMANAGE_MATCH_DIR/local/Config/database.php"
+
+    if [[ ! -e "$database_config" ]]; then
+        cat > "$database_config" <<EOF
+<?php
+ return [
+  'Datasources' => [
+   'default' => [
+    'className' => 'Cake\Database\Connection',
+    // Postgres is currently the only supported backend for COmanage Match
+    'driver' => 'Cake\Database\Driver\Postgres',
+    'host' => '${COMANAGE_MATCH_DATABASE_HOST:-comanage-match-database}',
+    'username' => '${COMANAGE_MATCH_DATABASE_USER:-match_user}',
+    'password' => '${COMANAGE_MATCH_DATABASE_USER_PASSWORD:-password}',
+    'database' => '${COMANAGE_MATCH_DATABASE:-match}',
+   ]
+  ]
+ ];
+EOF
+        echo "Wrote new database configuration file ${database_config}" > "$OUTPUT"
+    fi
+}
+
+##########################################
+# Prepare cert and key for HTTPS
+# Globals:
+#   HTTPS_CERT_FILE
+#   HTTPS_PRIVKEY_FILE
+# Arguments:
+#   None
+# Returns:
+#   None
+##########################################
+function comanage_utils::prepare_https_cert_key() {
+
+    local cert_path
+    local privkey_path
+    local web_user
+
+    if [[ -e '/etc/debian_version' ]]; then
+        cert_path='/etc/apache2/cert.pem'
+        privkey_path='/etc/apache2/privkey.pem'
+        web_user='www-data'
+    elif [[ -e '/etc/centos-release' ]]; then
+        cert_path='/etc/httpd/cert.pem'
+        privkey_path='/etc/httpd/privkey.pem'
+        web_user='apache'
+    fi
+
+    # If defined use configured location of Apache HTTP Server 
+    # HTTPS certificate and key files. The certificate file may also
+    # include intermediate CA certificates, sorted from leaf to root.
+    if [[ -n "${HTTPS_CERT_FILE}" ]]; then
+        rm -f "${cert_path}"
+        cp "${HTTPS_CERT_FILE}" "${cert_path}"
+        chown "${web_user}" "${cert_path}"
+        chmod 0644 "${cert_path}"
+        echo "Copied HTTPS certificate file ${HTTPS_CERT_FILE} to ${cert_path}" > "$OUTPUT"
+        echo "Set ownership of ${cert_path} to ${web_user}" > "$OUTPUT"
+    fi
+
+    if [[ -n "${HTTPS_PRIVKEY_FILE}" ]]; then
+        rm -f "${privkey_path}"
+        cp "${HTTPS_PRIVKEY_FILE}" "${privkey_path}"
+        chown "${web_user}" "${privkey_path}"
+        chmod 0600 "${privkey_path}"
+        echo "Copied HTTPS private key file ${HTTPS_PRIVKEY_FILE} to ${privkey_path}" > "$OUTPUT"
+        echo "Set ownership of ${privkey_path} to ${web_user}" > "$OUTPUT"
+    fi
+}
+
+##########################################
+# Prepare local directory structure
+# Globals:
+#   COMANAGE_MATCH_DIR
+# Arguments:
+#   None
+# Returns:
+#   None
+##########################################
+function comanage_utils::prepare_local_directory() {
+
+    # Make sure the directory structure we need is available
+    # in the data volume for $COMANAGE_MATCH_DIR/local
+    local directories
+
+    declare -a directories=("Config"
+                            )
+
+    local dir
+    local full_path
+    for dir in "${directories[@]}"
+    do
+        full_path="${COMANAGE_MATCH_DIR}/local/${dir}"
+        if [[ ! -d "${full_path}" ]]; then
+            mkdir -p "${full_path}" > "$OUTPUT" 2>&1
+            echo "Created directory ${full_path}"
+        fi
+    done
+}
+
+##########################################
+# Prepare web server name
+# Globals:
+#   COMANAGE_MATCH_VIRTUAL_HOST_FQDN
+# Arguments:
+#   None
+# Returns:
+#   None
+##########################################
+function comanage_utils::prepare_server_name() {
+    
+    # If COMANAGE_MATCH_VIRTUAL_HOST_FQDN has not been injected try to determine
+    # it from the HTTPS_CERT_FILE.
+    if [[ -z "$COMANAGE_MATCH_VIRTUAL_HOST_FQDN" ]]; then
+        COMANAGE_MATCH_VIRTUAL_HOST_FQDN=$(openssl x509 -in /etc/apache2/cert.pem -text -noout | 
+                      sed -n '/X509v3 Subject Alternative Name:/ {n;p}' | 
+                      sed -E 's/.*DNS:(.*)\s*$/\1/')
+        if [[ -n "$COMANAGE_MATCH_VIRTUAL_HOST_FQDN" ]]; then
+            echo "Set COMANAGE_MATCH_VIRTUAL_HOST_FQDN=${COMANAGE_MATCH_VIRTUAL_HOST_FQDN} using Subject Alternative Name from x509 certificate" > "$OUTPUT"
+        else
+            COMANAGE_MATCH_VIRTUAL_HOST_FQDN=$(openssl x509 -in /etc/apache2/cert.pem -subject -noout | 
+                          sed -E 's/subject=.*CN=(.*)\s*/\1/')
+            if [[ -n "$COMANAGE_MATCH_VIRTUAL_HOST_FQDN" ]]; then
+                echo "Set COMANAGE_MATCH_VIRTUAL_HOST_FQDN=${COMANAGE_MATCH_VIRTUAL_HOST_FQDN} using CN from x509 certificate" > "$OUTPUT"
+            fi
+        fi
+    fi
+
+    # Configure Apache HTTP Server with the server name.
+    # This configures the server name for the default Debian
+    # Apache HTTP Server configuration but not the server name used
+    # by any virtual hosts.
+    if [[ -e '/etc/debian_version' ]]; then
+        cat > /etc/apache2/conf-available/server-name.conf <<EOF
+ServerName ${COMANAGE_MATCH_VIRTUAL_HOST_FQDN:-unknown}
+EOF
+        a2enconf server-name.conf > "$OUTPUT" 2>&1
+    fi
+
+    # Export the server name so that it may be used by 
+    # Apache HTTP Server virtual host configurations.
+    export COMANAGE_MATCH_VIRTUAL_HOST_FQDN
+}
+
+##########################################
+# Clear CakePHP cache files
+# Globals:
+#   None
+# Arguments:
+#   None
+# Returns:
+#   None
+##########################################
+function comanage_utils::match_clear_cache() {
+
+    pushd "$COMANAGE_MATCH_DIR/app" > "$OUTPUT" 2>&1
+    ./bin/cake schema_cache clear > "$OUTPUT" 2>&1
+    popd > "$OUTPUT" 2>&1
+}
+
+##########################################
+# Run COmanage Match setup shell command
+# Globals:
+#   COMANAGE_MATCH_ADMIN_USERNAME
+#   COMANAGE_MATCH_DIR
+#   COMANAGE_MATCH_SECURITY_SALT
+#   COMANAGE_MATCH_SECURITY_SEED
+#   OUTPUT
+# Arguments:
+#   None
+# Returns:
+#   None
+##########################################
+function comanage_utils::match_setup() {
+
+    # We only want to run the setup script once since it creates
+    # state in the database. 
+    local auto_generated_security
+    pushd "$COMANAGE_MATCH_DIR/app" > "$OUTPUT" 2>&1
+    echo "Testing if COmanage Match setup has been done previously..." > "$OUTPUT"
+    if ! ./bin/cake databaseSetupAlready > "$OUTPUT" 2>&1; then
+        echo "COmanage Match database is not setup yet..." > "$OUTPUT"
+        rm -f "$COMANAGE_MATCH_DIR/local/Config/security.salt" > "$OUTPUT" 2>&1
+        echo "Running ./bin/cake setup..." > "$OUTPUT"
+        ./bin/cake setup --admin-username "${COMANAGE_MATCH_ADMIN_USERNAME}" > "$OUTPUT" 2>&1
+        echo "Set admin username ${COMANAGE_MATCH_ADMIN_USERNAME}" > "$OUTPUT"
+        auto_generated_security=1
+    fi
+
+    popd > "$OUTPUT" 2>&1
+
+    comanage_utils::match_clear_cache
+
+    # If COmanage Match CakePHP security salt has been
+    # injected and the files do not otherwise exist create them.
+    if [[ -n "$COMANAGE_MATCH_SECURITY_SALT" &&
+          ( -n "$auto_generated_security" || ! -e "$COMANAGE_MATCH_DIR/local/Config/security.salt" ) ]]; then
+        echo "$COMANAGE_MATCH_SECURITY_SALT" > "$COMANAGE_MATCH_DIR/local/Config/security.salt"
+    fi
+}
+
+##########################################
+# Set tmp directory file ownership
+# Globals:
+#   COMANAGE_MATCH_DIR
+# Arguments:
+#   None
+# Returns:
+#   None
+##########################################
+function comanage_utils::tmp_ownership() {
+
+    # Ensure that the web server user owns the tmp directory
+    # and all children.
+    local tmp_dir
+    local ownership
+
+    if [[ -e '/etc/debian_version' ]]; then
+        ownership='www-data:www-data'
+    elif [[ -e '/etc/centos-release' ]]; then
+        ownership='apache:apache'
+    fi
+
+    tmp_dir="${COMANAGE_MATCH_DIR}/app/tmp"
+
+    chown -R "${ownership}" "${tmp_dir}"
+
+    echo "Recursively set ownership of ${tmp_dir} to ${ownership}" > "$OUTPUT"
+
+}
+
+##########################################
+# Wait until able to connect to database
+# Globals:
+#   COMANAGE_MATCH_DIR
+#   OUTPUT
+# Arguments:
+#   None
+# Returns:
+#   None
+##########################################
+function comanage_utils::wait_database_connectivity() {
+    pushd "$COMANAGE_MATCH_DIR/app" > "$OUTPUT" 2>&1
+
+    # Loop until we are able to open a connection to the database.
+    echo "Testing database connectivity..." > "$OUTPUT"
+    until ./bin/cake databaseConnectivityTest > "$OUTPUT" 2>&1; do
+        >&2 echo "Database is unavailable - sleeping"
+        sleep 1
+    done
+
+    echo "Database is available" > "$OUTPUT"
+
+    popd > "$OUTPUT" 2>&1
+}
diff --git a/comanage-match-base/docker-comanage-match-entrypoint b/comanage-match-base/docker-comanage-match-entrypoint
new file mode 100755
index 0000000..2200e7d
--- /dev/null
+++ b/comanage-match-base/docker-comanage-match-entrypoint
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+# COmanage Match Dockerfile entrypoint
+#
+# Portions licensed to the University Corporation for Advanced Internet
+# Development, Inc. ("UCAID") under one or more contributor license agreements.
+# See the NOTICE file distributed with this work for additional information
+# regarding copyright ownership.
+#
+# UCAID licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+source /usr/local/lib/comanage_utils.sh
+
+comanage_utils::exec_apache_http_server "$@"
diff --git a/comanage-match-basic-auth/.dockerignore b/comanage-match-basic-auth/.dockerignore
new file mode 100644
index 0000000..b43bf86
--- /dev/null
+++ b/comanage-match-basic-auth/.dockerignore
@@ -0,0 +1 @@
+README.md
diff --git a/comanage-match-basic-auth/000-comanage.conf b/comanage-match-basic-auth/000-comanage.conf
new file mode 100644
index 0000000..bb8bff1
--- /dev/null
+++ b/comanage-match-basic-auth/000-comanage.conf
@@ -0,0 +1,42 @@
+# COmanage Match Apache HTTP Server configuration
+#
+# Portions licensed to the University Corporation for Advanced Internet
+# Development, Inc. ("UCAID") under one or more contributor license agreements.
+# See the NOTICE file distributed with this work for additional information
+# regarding copyright ownership.
+#
+# UCAID licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+Include apache-include-virtual-host-port80-redirect
+
+<VirtualHost *:443>
+
+Include apache-include-virtual-host-port443-base
+
+SSLCertificateFile /etc/apache2/cert.pem
+SSLCertificateKeyFile /etc/apache2/privkey.pem
+
+ErrorLog ${APACHE_LOG_DIR}/error.log
+CustomLog ${APACHE_LOG_DIR}/access.log combined
+
+Include apache-include-directory-match
+
+<Directory /var/www/html/match/auth/login>
+AuthType Basic
+AuthName "COmanage Match Login"
+AuthBasicProvider file
+AuthUserFile "/etc/apache2/basic-auth"
+Require valid-user
+</Directory>
+
+</VirtualHost>
diff --git a/comanage-match-basic-auth/Dockerfile b/comanage-match-basic-auth/Dockerfile
new file mode 100644
index 0000000..f72e378
--- /dev/null
+++ b/comanage-match-basic-auth/Dockerfile
@@ -0,0 +1,30 @@
+# COmanage Match Dockerfile template
+#
+# Portions licensed to the University Corporation for Advanced Internet
+# Development, Inc. ("UCAID") under one or more contributor license agreements.
+# See the NOTICE file distributed with this work for additional information
+# regarding copyright ownership.
+#
+# UCAID licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+ARG COMANAGE_MATCH_VERSION=develop
+ARG COMANAGE_MATCH_BASE_IMAGE_VERSION=1
+FROM comanage-match-base:${COMANAGE_MATCH_VERSION}-${COMANAGE_MATCH_BASE_IMAGE_VERSION}
+
+ARG COMANAGE_MATCH_BASE_IMAGE_VERSION
+ENV COMANAGE_MATCH_BASE_IMAGE_VERSION ${COMANAGE_MATCH_BASE_IMAGE_VERSION}
+LABEL comanage_match_base_image_version=${COMANAGE_MATCH_BASE_IMAGE_VERSION}
+
+COPY basic-auth /etc/apache2/
+COPY 000-comanage.conf /etc/apache2/sites-available/
+
+RUN a2ensite 000-comanage
diff --git a/comanage-match-basic-auth/README.md b/comanage-match-basic-auth/README.md
new file mode 100644
index 0000000..a485a02
--- /dev/null
+++ b/comanage-match-basic-auth/README.md
@@ -0,0 +1,132 @@
+<!--
+COmanage Docker documentation
+
+Portions licensed to the University Corporation for Advanced Internet
+Development, Inc. ("UCAID") under one or more contributor license agreements.
+See the NOTICE file distributed with this work for additional information
+regarding copyright ownership.
+
+UCAID licenses this file to you under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with the
+License. You may obtain a copy of the License at:
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+# COmanage Match Basic Auth
+
+Intended to build a COmanage Match image using Apache HTTP Server Basic Auth 
+(Basic Auth) as the authentication mechanism. 
+
+Basic Auth is only suitable for COmanage Match deployments
+not operating in a federated identity context, or for an introduction
+to COmanage Match. 
+
+See other documentation in this repository for examples on how to build images 
+that support federated identity deployments.
+
+## Build Arguments
+
+Building the image requires the following build arguments:
+
+```
+--build-arg COMANAGE_MATCH_VERSION=<version number>
+--build-arg COMANAGE_MATCH_BASE_IMAGE_VERSION=<base image version number>
+```
+
+## Build Requirements
+
+This image uses a [multi-stage build](https://docs.docker.com/develop/develop-images/multistage-build/)
+and requires that the [COmanage Match base image](../comanage-match-base/README.md) be built first.
+
+## Building
+
+
+```
+docker build \
+  --build-arg COMANAGE_MATCH_VERSION=<COmanage Match version number> \
+  --build-arg COMANAGE_MATCH_BASE_IMAGE_VERSION=<base image version number> \
+  -t comanage-match:<tag> .
+```
+
+## Building Example
+
+```
+export COMANAGE_MATCH_VERSION=1.0.0
+export COMANAGE_MATCH_BASE_IMAGE_VERSION=1
+export COMANAGE_MATCH_BASIC_AUTH_IMAGE_VERSION=1
+TAG="${COMANAGE_MATCH_VERSION}-basic-auth-${COMANAGE_MATCH_BASIC_AUTH_IMAGE_VERSION}" 
+docker build \
+  --build-arg COMANAGE_MATCH_VERSION=${COMANAGE_MATCH_VERSION} \
+  --build-arg COMANAGE_MATCH_BASE_IMAGE_VERSION=${COMANAGE_MATCH_BASE_IMAGE_VERSION} \
+  -t comanage-match:$TAG .
+```
+
+## Volumes and Data Persistence
+
+See [COmanage Match Volumes and Data Persistence](../docs/volumes-and-data-persistence.md).
+
+## Environment Variables
+
+See the [list of environment variables common to all images](../docs/comanage-match-common-environment-variables.md)
+including this image.
+
+## Authentication
+
+This image supports using Apache HTTP Server Basic Auth (Basic Auth) as the
+authentication mechanism. To aid simple deployments for evaluating and
+learning COmanage Registry a password file with a single user and password
+is included. See the section above on environment variables.
+
+To override the default bind mount or COPY in a password file created
+with the `htpasswd` command line tool. For example
+
+```
+COPY passwords /etc/apache2/passwords
+```
+
+## Ports
+
+The image listens for web traffic on ports 80 and 443. All requests
+on port 80 are redirected to port 443.
+
+## Running
+
+See other documentation in this repository for details on how to orchestrate
+running this image with other images using an orchestration tool like
+Docker Compose, Docker Swarm, or Kubernetes.
+
+To run this image:
+
+```
+docker run -d \
+  --name comanage-match \
+  -v /opt/comanage-match-local:/srv/comanage-match/local \
+  -p 80:80 \
+  -p 443:443 \
+  comanage-match:1.0.0-basic-auth-1
+```
+
+## Logging
+
+Both Apache HTTP Server and COmanage Match log to the stdout and
+stderr of the container.
+
+## HTTPS Configuration
+
+See the section on environment variables and the `HTTPS_CERT_FILE` and
+`HTTPS_PRIVKEY_FILE` variables.
+
+Additionally you may bind mount or COPY in an X.509 certificate file (containing the CA signing certificate(s), if any)
+and associated private key file. For example
+
+```
+COPY cert.pem /etc/apache2/cert.pem
+COPY privkey.pem /etc/apache2/privkey.pem
+```
diff --git a/comanage-match-basic-auth/basic-auth b/comanage-match-basic-auth/basic-auth
new file mode 100644
index 0000000..fee8aa3
--- /dev/null
+++ b/comanage-match-basic-auth/basic-auth
@@ -0,0 +1 @@
+match.admin:$apr1$qqrvav7G$nSHYErU4ljDPmO1wNBG6e0
diff --git a/comanage-match-internet2-tap-base/.dockerignore b/comanage-match-internet2-tap-base/.dockerignore
new file mode 100644
index 0000000..b43bf86
--- /dev/null
+++ b/comanage-match-internet2-tap-base/.dockerignore
@@ -0,0 +1 @@
+README.md
diff --git a/comanage-match-internet2-tap-base/Dockerfile b/comanage-match-internet2-tap-base/Dockerfile
new file mode 100644
index 0000000..3d87e13
--- /dev/null
+++ b/comanage-match-internet2-tap-base/Dockerfile
@@ -0,0 +1,102 @@
+# COmanage Match Dockerfile
+#
+# Portions licensed to the University Corporation for Advanced Internet
+# Development, Inc. ("UCAID") under one or more contributor license agreements.
+# See the NOTICE file distributed with this work for additional information
+# regarding copyright ownership.
+#
+# UCAID licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+FROM centos:centos7 AS php-build
+
+ARG PHP_VERSION=7.3.5
+ARG PHP_SRC_URL=https://github.com/php/php-src/archive/php-${PHP_VERSION}.tar.gz
+
+RUN yum -y install epel-release \
+        && yum clean all
+
+RUN yum -y update \
+        && yum -y install \
+            autoconf \
+            bison \
+            gcc \
+            gcc-c++ \
+            httpd-devel \
+            libargon2-devel \
+            libcurl-devel \
+            libedit-devel \
+            libicu-devel \
+            libsodium-devel \
+            libxml2-devel \
+            libxslt-devel \
+            make \
+            openssl-devel \
+            postgresql-devel \
+            re2c \
+            wget \
+        && yum clean all
+
+WORKDIR /usr/local/src
+
+RUN mkdir php-src \
+        && wget -O php-src.tar.gz ${PHP_SRC_URL} \
+        && tar zxf php-src.tar.gz -C php-src --strip-components=1 \
+        && rm php-src.tar.gz
+
+ENV PHP_CFLAGS="-fstack-protector-strong -fpic -fpie -O2"
+ENV PHP_CPPFLAGS="$PHP_CFLAGS"
+ENV PHP_LDFLAGS="-Wl,-O1 -Wl,--hash-style=both -pie"
+
+RUN cd php-src \
+        && ./buildconf --force \
+        && ./configure \
+            --disable-cgi \
+            --enable-mbstring \
+            --enable-intl \
+            --with-apxs2=/usr/bin/apxs \
+            --with-config-file-path=/usr/local/etc/php \
+            --with-config-file-scan-dir=/usr/local/etc/php/conf.d \
+            --with-curl \
+            --with-libdir=lib64 \
+            --with-libedit \
+            --with-openssl \
+            --with-password-argon2 \
+            --with-pdo-pgsql \
+            --with-pgsql \
+            --with-sodium \
+            --with-zlib \
+        && export CFLAGS="$PHP_CFLAGS" \
+        && export CPPFLAGS="$PHP_CPPFLAGS" \
+        && export LDFLAGS="$PHP_LDFLAGS" \
+        && make -j "$(nproc)" \
+        && make install 
+
+RUN rm -rf php-src \
+    && yum -y remove \
+            autoconf \
+            bison \
+            gcc \
+            gcc-c++ \
+            httpd-devel \
+            libargon2-devel \
+            libcurl-devel \
+            libedit-devel \
+            libicu-devel \
+            libsodium-devel \
+            libxml2-devel \
+            libxslt-devel \
+            make \
+            openssl-devel \
+            postgresql-devel \
+            re2c \
+            wget \
+    && yum clean all
diff --git a/comanage-match-internet2-tap-base/README.md b/comanage-match-internet2-tap-base/README.md
new file mode 100644
index 0000000..79d283a
--- /dev/null
+++ b/comanage-match-internet2-tap-base/README.md
@@ -0,0 +1,58 @@
+<!--
+COmanage Docker documentation
+
+Portions licensed to the University Corporation for Advanced Internet
+Development, Inc. ("UCAID") under one or more contributor license agreements.
+See the NOTICE file distributed with this work for additional information
+regarding copyright ownership.
+
+UCAID licenses this file to you under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with the
+License. You may obtain a copy of the License at:
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+# COmanage Match Internet2 TAP Base Image
+
+Intended to build a COmanage Match for Internet2 TAP base image
+using CentOS 7 as the operating system and building PHP from source.
+
+By itself the image built from this Dockerfile does **not** provide
+COmanage Match.
+
+The image built from this Dockerfile is used as the base
+for the Internet2 TAP image that includes COmanage Match
+with the Shibboleth Native SP for Apache HTTP Server (Shibboleth)
+as the authentication mechanism.
+
+## Build Arguments
+
+No arguments are required for the build but the following argument
+may be provided to override the default:
+
+```
+--build-arg PHP_VERSION=<PHP version number>
+```
+
+## Building
+
+```
+docker build \
+    -t comanage-match-internet2-tier-base:<tag> .
+```
+
+## Building Example
+
+```
+export COMANAGE_MATCH_I2_BASE_IMAGE_VERSION=1
+TAG="${COMANAGE_MATCH_I2_BASE_IMAGE_VERSION}"
+docker build \
+    -t comanage-match-internet2-tap-base:${TAG} .
+```
diff --git a/comanage-match-internet2-tap/.dockerignore b/comanage-match-internet2-tap/.dockerignore
new file mode 100644
index 0000000..b43bf86
--- /dev/null
+++ b/comanage-match-internet2-tap/.dockerignore
@@ -0,0 +1 @@
+README.md
diff --git a/comanage-match-internet2-tap/000-comanage.conf b/comanage-match-internet2-tap/000-comanage.conf
new file mode 100644
index 0000000..4b6bbb8
--- /dev/null
+++ b/comanage-match-internet2-tap/000-comanage.conf
@@ -0,0 +1,65 @@
+# COmanage Match Apache HTTP Server configuration
+#
+# Portions licensed to the University Corporation for Advanced Internet
+# Development, Inc. ("UCAID") under one or more contributor license agreements.
+# See the NOTICE file distributed with this work for additional information
+# regarding copyright ownership.
+#
+# UCAID licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+Listen 443
+ServerName ${COMANAGE_MATCH_VIRTUAL_HOST_FQDN}
+PassEnv ENV
+PassEnv USERTOKEN
+
+Include apache-include-virtual-host-port80-redirect
+
+<VirtualHost *:443>
+
+Include apache-include-virtual-host-port443-base
+
+SSLCertificateFile /etc/httpd/cert.pem
+SSLCertificateKeyFile /etc/httpd/privkey.pem
+
+PassEnv ENV
+PassEnv USERTOKEN
+
+ErrorLogFormat "httpd;ssl_error_log;%{ENV}e;%{USERTOKEN}e;[%{u}t] [%-m:%l] [pid %P:tid %T] %7F: %E: [client\ %a] %M% ,\ referer\ %{Referer}i"
+ErrorLog /tmp/logpipe
+LogLevel warn
+
+LogFormat "httpd;ssl_access_log;%{ENV}e;%{USERTOKEN}e;%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" ssl_combined
+CustomLog /tmp/logpipe ssl_combined
+
+Include apache-include-directory-match
+
+<Location "/Shibboleth.sso">
+SetHandler shib
+</Location>
+
+<Directory /var/www/html/match/auth/login>
+AuthType shibboleth
+ShibRequestSetting requireSession 1
+Require valid-user
+</Directory>
+
+<Location />
+AuthType shibboleth
+Require shibboleth
+</Location>
+
+RewriteEngine On
+RewriteCond %{QUERY_STRING} !after_redirect
+RewriteRule ^/match/auth/logout.* https://%{HTTP_HOST}/Shibboleth.sso/Logout?return=https://%{HTTP_HOST}/match/auth/logout/?after_redirect [L,R]
+
+</VirtualHost>
diff --git a/comanage-match-internet2-tap/10-php7.conf b/comanage-match-internet2-tap/10-php7.conf
new file mode 100644
index 0000000..64ef2d7
--- /dev/null
+++ b/comanage-match-internet2-tap/10-php7.conf
@@ -0,0 +1,3 @@
+<IfModule prefork.c>
+  LoadModule php7_module modules/libphp7.so
+</IfModule>
diff --git a/comanage-match-internet2-tap/Dockerfile b/comanage-match-internet2-tap/Dockerfile
new file mode 100644
index 0000000..ec2d39e
--- /dev/null
+++ b/comanage-match-internet2-tap/Dockerfile
@@ -0,0 +1,137 @@
+# COmanage Dockerfile
+#
+# Portions licensed to the University Corporation for Advanced Internet
+# Development, Inc. ("UCAID") under one or more contributor license agreements.
+# See the NOTICE file distributed with this work for additional information
+# regarding copyright ownership.
+#
+# UCAID licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+ARG COMANAGE_MATCH_VERSION=develop
+ARG COMANAGE_MATCH_BASE_IMAGE_VERSION=1
+ARG COMANAGE_MATCH_I2_BASE_IMAGE_VERSION=1
+
+FROM comanage-match-base:${COMANAGE_MATCH_VERSION}-${COMANAGE_MATCH_BASE_IMAGE_VERSION} AS comanage
+
+FROM comanage-match-internet2-tap-base:${COMANAGE_MATCH_I2_BASE_IMAGE_VERSION} AS php-build
+
+FROM centos:centos7
+
+ARG COMANAGE_MATCH_VERSION
+ENV COMANAGE_MATCH_VERSION ${COMANAGE_MATCH_VERSION}
+LABEL comanage_match_version=${COMANAGE_MATCH_VERSION}
+
+ARG COMANAGE_MATCH_BASE_IMAGE_VERSION
+ENV COMANAGE_MATCH_BASE_IMAGE_VERSION ${COMANAGE_MATCH_BASE_IMAGE_VERSION}
+LABEL comanage_match_base_image_version=${COMANAGE_MATCH_BASE_IMAGE_VERSION}
+
+ARG COMANAGE_MATCH_I2_BASE_IMAGE_VERSION
+ENV COMANAGE_MATCH_I2_BASE_IMAGE_VERSION ${COMANAGE_MATCH_I2_BASE_IMAGE_VERSION}
+LABEL comanage_match_i2_base_image_version=${COMANAGE_MATCH_I2_BASE_IMAGE_VERSION}
+
+ARG COMANAGE_MATCH_DIR
+ENV COMANAGE_MATCH_DIR ${COMANAGE_MATCH_DIR:-/srv/comanage-match}
+LABEL comanage_match_dir=${COMANAGE_MATCH_DIR}
+
+RUN yum -y install epel-release
+
+COPY shibboleth.repo /etc/yum.repos.d/
+
+RUN yum -y update && yum -y install \
+        cronie \
+        httpd \
+        libargon2 \
+        libcurl \
+        libedit \
+        libicu \
+        libsodium \
+        libxml2 \
+        libxslt \
+        mod_ssl \
+        postgresql \
+        python-pip \
+        shibboleth \
+        sudo \
+        wget \
+        zlib \
+    && pip install --upgrade pip \
+    && pip install supervisor \
+    && yum clean -y all
+
+COPY --from=php-build /usr/lib64/httpd/modules/libphp7.so /usr/lib64/httpd/modules/
+COPY --from=php-build /usr/local/lib/php /usr/local/lib/php/
+COPY --from=php-build /usr/local/include/php /usr/local/include/php/
+COPY --from=php-build /usr/local/bin /usr/local/bin/
+
+COPY --from=comanage ${COMANAGE_MATCH_DIR} ${COMANAGE_MATCH_DIR}/
+COPY --from=comanage /etc/apache2/apache-include-directory-match /etc/httpd/
+COPY --from=comanage /etc/apache2/apache-include-virtual-host-port443-base /etc/httpd/
+COPY --from=comanage /etc/apache2/apache-include-virtual-host-port80-redirect /etc/httpd/
+COPY --from=comanage /usr/local/lib/comanage_utils.sh /usr/local/lib/
+COPY --from=comanage /usr/local/lib/comanage_shibboleth_sp_utils.sh /usr/local/lib/
+COPY --from=comanage /usr/local/bin/docker-comanage-match-entrypoint /usr/local/bin/
+
+COPY 000-comanage.conf /etc/httpd/conf.d/
+COPY 10-php7.conf /etc/httpd/conf.modules.d/
+COPY php.conf /etc/httpd/conf.d/
+COPY supervisord.conf /usr/local/etc/supervisord.conf
+COPY shibd.logger /etc/shibboleth/
+COPY native.logger /etc/shibboleth/
+COPY httpd.conf /etc/httpd/conf/
+COPY sendtierbeacon.sh /usr/local/bin/sendtierbeacon.sh
+COPY setupcron.sh /usr/local/bin/setupcron.sh
+COPY docker-comanage-entrypoint /usr/local/bin/
+COPY docker-comanage-shibboleth-sp-entrypoint /usr/local/bin/
+COPY docker-supervisord-entrypoint /usr/local/bin/
+
+RUN cd /etc/httpd/conf.d \
+    && rm -f autoindex.conf ssl.conf userdir.conf welcome.conf \
+    && cd /etc/httpd \
+    && ln -s /etc/pki/tls/certs/localhost.crt cert.pem \
+    && ln -s /etc/pki/tls/private/localhost.key privkey.pem \
+    && chmod 755 /usr/local/bin/sendtierbeacon.sh \
+    && chmod 755 /usr/local/bin/setupcron.sh \
+    && /usr/local/bin/setupcron.sh \
+    && cd /var/www/html \
+    && ln -s ${COMANAGE_MATCH_DIR}/app/webroot match \
+    && rm -rf ${COMANAGE_MATCH_DIR}/local/* \
+    && chown -R apache:apache ${COMANAGE_MATCH_DIR}/app/tmp
+
+# Allow value for first administrator bootstrapped into the
+# platform to be specified at image build time, in addition to
+# being injected at run time through the entrypoint script.
+ARG COMANAGE_MATCH_ADMIN_USERNAME
+
+# Set simple defaults for first administrator bootstrapped into the
+# platform to make simple evaluation of the platform easier.
+ENV COMANAGE_MATCH_ADMIN_USERNAME ${COMANAGE_MATCH_ADMIN_USERNAME:-match.admin}
+
+VOLUME ${COMANAGE_MATCH_DIR}/local /etc/shibboleth
+
+EXPOSE 80 443
+
+# TIER Beacon Opt-out
+#
+# Completely uncomment the following ENV line to prevent the containers from
+# sending analytics information to Internet2.  With the default/release
+# configuration, it will only send product (Shibb/Grouper/COmanage) and version
+# (3.3.1-17040, etc) once daily between midnight and 4am.  There is no
+# configuration or private information collected or sent.  This data helps with
+# the scaling and funding of TIER.  Please do not disable it if you find the
+# TIER tools useful.  To keep it commented, keep multiple comments on the
+# following line (to prevent other scripts from processing it).
+#####     ENV TIER_BEACON_OPT_OUT True
+
+ENV TIER_RELEASE=190527
+ENV TIER_MAINTAINER=tier
+
+ENTRYPOINT ["docker-supervisord-entrypoint"]
diff --git a/comanage-match-internet2-tap/README.md b/comanage-match-internet2-tap/README.md
new file mode 100644
index 0000000..43d64d7
--- /dev/null
+++ b/comanage-match-internet2-tap/README.md
@@ -0,0 +1,159 @@
+<!--
+COmanage Docker documentation
+
+Portions licensed to the University Corporation for Advanced Internet
+Development, Inc. ("UCAID") under one or more contributor license agreements.
+See the NOTICE file distributed with this work for additional information
+regarding copyright ownership.
+
+UCAID licenses this file to you under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with the
+License. You may obtain a copy of the License at:
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+# COmanage Match Internet2 TAP
+
+Intended to build a COmanage Match image using the Shibboleth Native SP
+for Apache HTTP Server (Shibboleth) as the authentication mechanism and that
+meets the 
+[TAP Docker Container Specification](https://spaces.at.internet2.edu/x/m4ZyBw)
+(previously the TIER specification)
+from the
+[Internet2 TAP](https://www.incommon.org/tap/)
+program.
+
+## Build Arguments
+
+Building the image requires the following build arguments:
+
+```
+--build-arg COMANAGE_MATCH_VERSION=<version number>
+--build-arg COMANAGE_MATCH_BASE_IMAGE_VERSION=<base image version number>
+--build-arg COMANAGE_MATCH_I2_BASE_IMAGE_VERSION=<I2 base image version number>
+```
+
+## Build Requirements
+
+This image uses a [multi-stage build](https://docs.docker.com/develop/develop-images/multistage-build/).
+It requires that the [COmanage Match base image](../comanage-match-base/README.md) 
+and [Internet2 TAP base image](../comanage-match-internet2-tap-base/README.md) be built first.
+
+## Building
+
+```
+docker build \
+  --build-arg COMANAGE_MATCH_VERSION=<COmanage Match version number> \
+  --build-arg COMANAGE_MATCH_BASE_IMAGE_VERSION=<base image version number> \
+  --build-arg COMANAGE_MATCH_I2_BASE_IMAGE_VERSION=<base image version number> \
+  -t comanage-match:<tag> .
+```
+
+## Building Example
+
+```
+export COMANAGE_MATCH_VERSION=1.0.0
+export COMANAGE_MATCH_BASE_IMAGE_VERSION=1
+export COMANAGE_MATCH_I2_BASE_IMAGE_VERSION=1
+export COMANAGE_MATCH_I2_IMAGE_VERSION=1
+TAG="${COMANAGE_MATCH_VERSION}-internet2-tap-${COMANAGE_MATCH_I2_IMAGE_VERSION}"
+docker build \
+  --build-arg COMANAGE_MATCH_VERSION=${COMANAGE_MATCH_VERSION} \
+  --build-arg COMANAGE_MATCH_BASE_IMAGE_VERSION=${COMANAGE_MATCH_BASE_IMAGE_VERSION} \
+  --build-arg COMANAGE_MATCH_I2_BASE_IMAGE_VERSION=${COMANAGE_MATCH_I2_BASE_IMAGE_VERSION} \
+  -t comanage-match:$TAG .
+```
+
+## Volumes and Data Persistence
+
+See [COmanage Match Volumes and Data Persistence](../docs/volumes-and-data-persistence.md).
+
+
+## Environment Variables
+
+See the [list of environment variables common to all images](../docs/comanage-match-common-environment-variables.md)
+including this image.
+
+See also the
+[list of environment variables common to all images using Shibboleth](../../docs/comanage-common-shibboleth-environment-variables.md).
+
+Additionally the Internet2 TAP image supports the following environment variables:
+
+`ENV`
+
+* Description: Environment
+* Required: No
+* Default: None
+* Example: PROD
+* Note: Usually one of PROD, TEST, or DEV. The value is included in log entries.
+
+`USERTOKEN`
+
+* Description: Deployer supplied
+* Required: No
+* Default: None
+* Example: node01
+* Note: The value is included in log entries.
+
+## Authentication
+
+This image supports using the Shibboleth Native SP for Apache HTTP Server (Shibboleth) as the
+authentication mechanism. Deployers should configure Shibboleth so that the desired
+asserted user attribute is written into `REMOTE_USER`.
+
+## Ports
+
+The image listens for web traffic on ports 80 and 443. All requests
+on port 80 are redirected to port 443.
+
+## Running
+
+See other documentation in this repository for details on how to orchestrate
+running this image with other images using an orchestration tool like
+Docker Compose, Docker Swarm, or Kubernetes.
+
+To run this image:
+
+```
+docker run -d \
+  --name comanage-match \
+  -e COMANAGE_MATCH_ADMIN_USERNAME=julia.janseen@my.org \
+  -e SHIBBOLETH_SP_ENTITY_ID=https://myapp.my.org/shibboleth/sp \
+  -e SHIBBOLETH_SP_METADATA_PROVIDER_XML_FILE=/etc/shibboleth/my-org-metadata.xml \
+  -v /opt/comanage-match-local:/srv/comanage-match/local \
+  -v /etc/shibboleth/sp-encrypt-cert.pem:/etc/shibboleth/sp-encrypt-cert.pem \
+  -v /etc/shibboleth/sp-encrypt-key.pem:/etc/shibboleth/sp-encrypt-key.pem \
+  -v /etc/shibboleth/my-org-metadata.xml:/etc/shibboleth/my-org-metadata.xml \
+  -p 80:80 \
+  -p 443:443 \
+  comanage-match:1.0.0-internet2-tap-1
+```
+
+## Logging
+
+Apache HTTP Server, COmanage Match, Shibboleth, and supervisord all log to the stdout and
+stderr of the container.
+
+The logging configuration meets version 1 of the
+[TAP Docker Container Specification](https://spaces.at.internet2.edu/x/m4ZyBw)
+(formerly the TIER Docker Container Specification).
+
+## HTTPS Configuration
+
+See the section on environment variables and the `HTTPS_CERT_FILE` and
+`HTTPS_PRIVKEY_FILE` variables.
+
+Additionally you may bind mount or COPY in an X.509 certificate file (containing the CA signing certificate(s), if any)
+and associated private key file. For example
+
+```
+COPY cert.pem /etc/httpd/cert.pem
+COPY privkey.pem /etc/httpd/privkey.pem
+```
diff --git a/comanage-match-internet2-tap/docker-comanage-entrypoint b/comanage-match-internet2-tap/docker-comanage-entrypoint
new file mode 100755
index 0000000..5ac645f
--- /dev/null
+++ b/comanage-match-internet2-tap/docker-comanage-entrypoint
@@ -0,0 +1,46 @@
+#!/bin/bash
+
+# COmanage Match Dockerfile entrypoint
+#
+# Portions licensed to the University Corporation for Advanced Internet
+# Development, Inc. ("UCAID") under one or more contributor license agreements.
+# See the NOTICE file distributed with this work for additional information
+# regarding copyright ownership.
+#
+# UCAID licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+source /usr/local/lib/comanage_utils.sh
+
+comanage_utils::consume_injected_environment
+
+comanage_utils::prepare_local_directory
+
+comanage_utils::configure_tier_logging
+
+comanage_utils::prepare_database_config
+
+comanage_utils::prepare_https_cert_key
+
+comanage_utils::prepare_server_name
+
+comanage_utils::wait_database_connectivity
+
+comanage_utils::match_setup
+
+comanage_utils::match_clear_cache
+
+comanage_utils::tmp_ownership
+
+# Start Apache HTTP Server
+exec /usr/sbin/httpd -DFOREGROUND
diff --git a/comanage-match-internet2-tap/docker-comanage-shibboleth-sp-entrypoint b/comanage-match-internet2-tap/docker-comanage-shibboleth-sp-entrypoint
new file mode 100755
index 0000000..3abdd0f
--- /dev/null
+++ b/comanage-match-internet2-tap/docker-comanage-shibboleth-sp-entrypoint
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+# COmanage Match Shibboleth SP Dockerfile entrypoint
+#
+# Portions licensed to the University Corporation for Advanced Internet
+# Development, Inc. ("UCAID") under one or more contributor license agreements.
+# See the NOTICE file distributed with this work for additional information
+# regarding copyright ownership.
+#
+# UCAID licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+source /usr/local/lib/comanage_utils.sh
+
+source /usr/local/lib/comanage_shibboleth_sp_utils.sh
+
+comanage_utils::manage_tier_environment
+
+comanage_shibboleth_sp_utils::exec_shibboleth_sp_daemon
diff --git a/comanage-match-internet2-tap/docker-supervisord-entrypoint b/comanage-match-internet2-tap/docker-supervisord-entrypoint
new file mode 100755
index 0000000..d71c994
--- /dev/null
+++ b/comanage-match-internet2-tap/docker-supervisord-entrypoint
@@ -0,0 +1,60 @@
+#!/bin/bash
+
+# COmanage Match Dockerfile entrypoint
+#
+# Portions licensed to the University Corporation for Advanced Internet
+# Development, Inc. ("UCAID") under one or more contributor license agreements.
+# See the NOTICE file distributed with this work for additional information
+# regarding copyright ownership.
+#
+# UCAID licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+source /usr/local/lib/comanage_utils.sh
+
+comanage_utils::manage_tier_environment
+
+# Make a "console" logging pipe that anyone can write to regardless of who owns the process.
+rm -f /tmp/logpipe > "$OUTPUT" 2>&1
+mkfifo -m 666 /tmp/logpipe > "$OUTPUT" 2>&1
+cat <> /tmp/logpipe &
+
+# Format any console output from httpd into standard TIER form.
+rm -f /tmp/loghttpd > "$OUTPUT" 2>&1
+mkfifo -m 666 /tmp/loghttpd > "$OUTPUT" 2>&1
+(cat <> /tmp/loghttpd | awk -v ENV="$ENV" -v UT="$USERTOKEN" '{printf "httpd;console;%s;%s;%s\n", ENV, UT, $0; fflush()}' 1>/tmp/logpipe 2>&1)&
+
+# Format any console output from shibd into standard TIER form.
+rm -f /tmp/logshibd > "$OUTPUT" 2>&1
+mkfifo -m 666 /tmp/logshibd > "$OUTPUT" 2>&1
+(cat <> /tmp/logshibd | awk -v ENV="$ENV" -v UT="$USERTOKEN" '{printf "shibd;console;%s;%s;%s\n", ENV, UT, $0; fflush()}' 1>/tmp/logpipe 2>&1)&
+
+# Format any console output from supervisord into standard TIER form.
+rm -f /tmp/logsuperd > "$OUTPUT" 2>&1
+mkfifo -m 666 /tmp/logsuperd > "$OUTPUT" 2>&1
+(cat <> /tmp/logsuperd | awk -v ENV="$ENV" -v UT="$USERTOKEN" '{printf "supervisord;console;%s;%s;%s\n", ENV, UT, $0; fflush()}' 1>/tmp/logpipe 2>&1)&
+
+# Format any output from cron into standard TIER form.
+rm -f /var/log/cron > "$OUTPUT" 2>&1
+rm -f /tmp/logcrond > "$OUTPUT" 2>&1
+mkfifo -m 666 /tmp/logcrond > "$OUTPUT" 2>&1
+ln -s /tmp/logcrond /var/log/cron > "$OUTPUT" 2>&1
+(cat <> /tmp/logcrond | awk -v ENV="$ENV" -v UT="$USERTOKEN" '{printf "crond;cron;%s;%s;%s\n", ENV, UT, $0; fflush()}' 1>/tmp/logpipe 2>&1)&
+
+# Close stdout and stderr for this process since supervisord will write
+# to its logfile and its children are configured to write to different
+# pipes.
+exec 1<&-
+exec 2<&-
+
+# Start supervisord
+exec /usr/bin/supervisord -c /usr/local/etc/supervisord.conf
diff --git a/comanage-match-internet2-tap/httpd.conf b/comanage-match-internet2-tap/httpd.conf
new file mode 100644
index 0000000..b9ad500
--- /dev/null
+++ b/comanage-match-internet2-tap/httpd.conf
@@ -0,0 +1,74 @@
+# COmanage Match Apache HTTP Server configuration
+#
+# Portions licensed to the University Corporation for Advanced Internet
+# Development, Inc. ("UCAID") under one or more contributor license agreements.
+# See the NOTICE file distributed with this work for additional information
+# regarding copyright ownership.
+#
+# UCAID licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+ServerRoot "/etc/httpd"
+Listen 80
+Include conf.modules.d/*.conf
+User apache
+Group apache
+ServerAdmin root@localhost
+
+<Directory />
+    AllowOverride none
+    Require all denied
+</Directory>
+
+DocumentRoot "/var/www/html"
+
+<Directory "/var/www">
+    AllowOverride None
+    # Allow open access:
+    Require all granted
+</Directory>
+
+<Directory "/var/www/html">
+    Options Indexes FollowSymLinks
+    AllowOverride None
+    Require all granted
+</Directory>
+
+DirectoryIndex index.html
+
+<Files ".ht*">
+    Require all denied
+</Files>
+
+PassEnv ENV
+PassEnv USERTOKEN
+
+ErrorLogFormat "httpd;error_log;%{ENV}e;%{USERTOKEN}e;[%{u}t] [%-m:%l] [pid %P:tid %T] %7F: %E: [client\ %a] %M% ,\ referer\ %{Referer}i"
+ErrorLog "/tmp/logpipe"
+LogLevel warn
+
+LogFormat "httpd;access_log;%{ENV}e;%{USERTOKEN}e;%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
+CustomLog "/tmp/logpipe" combined
+
+TypesConfig /etc/mime.types
+AddType application/x-compress .Z
+AddType application/x-gzip .gz .tgz
+AddType text/html .shtml
+AddOutputFilter INCLUDES .shtml
+
+AddDefaultCharset UTF-8
+
+MIMEMagicFile conf/magic
+
+EnableSendfile on
+
+IncludeOptional conf.d/*.conf
diff --git a/comanage-match-internet2-tap/native.logger b/comanage-match-internet2-tap/native.logger
new file mode 100644
index 0000000..0b01f32
--- /dev/null
+++ b/comanage-match-internet2-tap/native.logger
@@ -0,0 +1,39 @@
+# set overall behavior
+log4j.rootCategory=INFO, native_log, warn_log
+
+# fairly verbose for DEBUG, so generally leave at INFO
+log4j.category.XMLTooling.XMLObject=INFO
+log4j.category.XMLTooling.KeyInfoResolver=INFO
+log4j.category.Shibboleth.IPRange=INFO
+log4j.category.Shibboleth.PropertySet=INFO
+
+# raise for low-level tracing of SOAP client HTTP/SSL behavior
+log4j.category.XMLTooling.libcurl=INFO
+
+# useful categories to tune independently:
+#
+# tracing of SAML messages and security policies
+#log4j.category.OpenSAML.MessageDecoder=DEBUG
+#log4j.category.OpenSAML.MessageEncoder=DEBUG
+#log4j.category.OpenSAML.SecurityPolicyRule=DEBUG
+# interprocess message remoting
+#log4j.category.Shibboleth.Listener=DEBUG
+# mapping of requests to applicationId
+#log4j.category.Shibboleth.RequestMapper=DEBUG
+# high level session cache operations
+#log4j.category.Shibboleth.SessionCache=DEBUG
+# persistent storage and caching
+#log4j.category.XMLTooling.StorageService=DEBUG
+
+# define the appender
+
+log4j.appender.native_log=org.apache.log4j.FileAppender
+log4j.appender.native_log.fileName=/tmp/logpipe
+log4j.appender.native_log.layout=org.apache.log4j.PatternLayout
+log4j.appender.native_log.layout.ConversionPattern=shibd;native.log;${ENV};${USERTOKEN};%d{%Y-%m-%d %H:%M:%S} %p %c %x: %m%n
+
+log4j.appender.warn_log=org.apache.log4j.FileAppender
+log4j.appender.warn_log.fileName=/tmp/logpipe
+log4j.appender.warn_log.layout=org.apache.log4j.PatternLayout
+log4j.appender.warn_log.layout.ConversionPattern=shibd;native_warn.log;${ENV};${USERTOKEN};%d{%Y-%m-%d %H:%M:%S} %p %c %x: %m%n
+log4j.appender.warn_log.threshold=WARN
diff --git a/comanage-match-internet2-tap/php.conf b/comanage-match-internet2-tap/php.conf
new file mode 100644
index 0000000..ffda6de
--- /dev/null
+++ b/comanage-match-internet2-tap/php.conf
@@ -0,0 +1,10 @@
+<FilesMatch \.php$>
+    SetHandler application/x-httpd-php
+</FilesMatch>
+
+AddType text/html .php
+
+DirectoryIndex index.php
+
+#php_value session.save_handler "files"
+#php_value session.save_path    "/var/lib/php/session"
diff --git a/comanage-match-internet2-tap/sendtierbeacon.sh b/comanage-match-internet2-tap/sendtierbeacon.sh
new file mode 100755
index 0000000..deb6e71
--- /dev/null
+++ b/comanage-match-internet2-tap/sendtierbeacon.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+
+# COmanage Match script to send TIER beacon
+#
+# Portions licensed to the University Corporation for Advanced Internet
+# Development, Inc. ("UCAID") under one or more contributor license agreements.
+# See the NOTICE file distributed with this work for additional information
+# regarding copyright ownership.
+#
+# UCAID licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOGHOST='collector.testbed.tier.internet2.edu'
+LOGPORT='5001'
+
+messagefile='/tmp/beaconmsg'
+
+if [[ -z "${TIER_BEACON_OPT_OUT}" ]]; then
+    cat > ${messagefile} <<EOF
+{
+    "msgType"          : "TIERBEACON",
+    "msgName"          : "TIER",
+    "msgVersion"       : "1.0",
+    "tbProduct"        : "COmanage Match",
+    "tbProductVersion" : "$COMANAGE_MATCH_VERSION",
+    "tbTIERRelease"    : "$TIER_RELEASE",
+    "tbMaintainer"     : "$TIER_MAINTAINER"
+}
+EOF
+
+    curl -s -XPOST "${LOGHOST}:${LOGPORT}/" -H 'Content-Type: application/json' -T ${messagefile} 1>/dev/null 2>&1
+    if [[ $? -eq 0 ]]; then
+        echo "tier_beacon;none;$ENV;$USERTOKEN;"`date`"; TIER beacon sent"
+    else
+        echo "tier_beacon;none;$ENV;$USERTOKEN;"`date`"; Failed to send TIER beacon"
+    fi
+
+    rm -f ${messagefile} 1>/dev/null 2>&1
+  
+fi
diff --git a/comanage-match-internet2-tap/setupcron.sh b/comanage-match-internet2-tap/setupcron.sh
new file mode 100755
index 0000000..5b81084
--- /dev/null
+++ b/comanage-match-internet2-tap/setupcron.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+# COmanage Match shell script to install TIER beacon crontab
+#
+# Portions licensed to the University Corporation for Advanced Internet
+# Development, Inc. ("UCAID") under one or more contributor license agreements.
+# See the NOTICE file distributed with this work for additional information
+# regarding copyright ownership.
+#
+# UCAID licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+CRONFILE='/tmp/cronfile'
+
+# Build and install crontab file with random start time
+# between midnight and 3:59am.
+echo '#send daily beacon to TIER Central' > "${CRONFILE}"
+echo $(expr $RANDOM % 59) $(expr $RANDOM % 3) "* * * /usr/local/bin/sendtierbeacon.sh >> /tmp/logpipe 2>&1" >> "${CRONFILE}"
+chmod 644 "${CRONFILE}"
+crontab "${CRONFILE}"
diff --git a/comanage-match-internet2-tap/shibboleth.repo b/comanage-match-internet2-tap/shibboleth.repo
new file mode 100644
index 0000000..02877bb
--- /dev/null
+++ b/comanage-match-internet2-tap/shibboleth.repo
@@ -0,0 +1,8 @@
+[shibboleth]
+name=Shibboleth (CentOS_7)
+# Please report any problems to https://issues.shibboleth.net
+type=rpm-md
+mirrorlist=https://shibboleth.net/cgi-bin/mirrorlist.cgi/CentOS_7
+gpgcheck=1
+gpgkey=https://shibboleth.net/downloads/service-provider/RPMS/repomd.xml.key
+enabled=1
diff --git a/comanage-match-internet2-tap/shibd.logger b/comanage-match-internet2-tap/shibd.logger
new file mode 100644
index 0000000..41300f2
--- /dev/null
+++ b/comanage-match-internet2-tap/shibd.logger
@@ -0,0 +1,63 @@
+# set overall behavior
+log4j.rootCategory=INFO, shibd_log, warn_log
+
+# fairly verbose for DEBUG, so generally leave at INFO
+log4j.category.XMLTooling.XMLObject=INFO
+log4j.category.XMLTooling.KeyInfoResolver=INFO
+log4j.category.Shibboleth.IPRange=INFO
+log4j.category.Shibboleth.PropertySet=INFO
+
+# raise for low-level tracing of SOAP client HTTP/SSL behavior
+log4j.category.XMLTooling.libcurl=INFO
+
+# useful categories to tune independently:
+#
+# tracing of SAML messages and security policies
+#log4j.category.OpenSAML.MessageDecoder=DEBUG
+#log4j.category.OpenSAML.MessageEncoder=DEBUG
+#log4j.category.OpenSAML.SecurityPolicyRule=DEBUG
+#log4j.category.XMLTooling.SOAPClient=DEBUG
+# interprocess message remoting
+#log4j.category.Shibboleth.Listener=DEBUG
+# mapping of requests to applicationId
+#log4j.category.Shibboleth.RequestMapper=DEBUG
+# high level session cache operations
+#log4j.category.Shibboleth.SessionCache=DEBUG
+# persistent storage and caching
+#log4j.category.XMLTooling.StorageService=DEBUG
+
+# logs XML being signed or verified if set to DEBUG
+log4j.category.XMLTooling.Signature.Debugger=INFO, sig_log
+log4j.additivity.XMLTooling.Signature.Debugger=false
+
+# the tran log blocks the "default" appender(s) at runtime
+# Level should be left at INFO for this category
+log4j.category.Shibboleth-TRANSACTION=INFO, tran_log
+log4j.additivity.Shibboleth-TRANSACTION=false
+# uncomment to suppress particular event types
+#log4j.category.Shibboleth-TRANSACTION.AuthnRequest=WARN
+#log4j.category.Shibboleth-TRANSACTION.Login=WARN
+#log4j.category.Shibboleth-TRANSACTION.Logout=WARN
+
+# define the appenders
+
+log4j.appender.shibd_log=org.apache.log4j.FileAppender
+log4j.appender.shibd_log.fileName=/tmp/logpipe
+log4j.appender.shibd_log.layout=org.apache.log4j.PatternLayout
+log4j.appender.shibd_log.layout.ConversionPattern=shibd;shibd.log;${ENV};${USERTOKEN};%d{%Y-%m-%d %H:%M:%S} %p %c %x: %m%n
+
+log4j.appender.warn_log=org.apache.log4j.FileAppender
+log4j.appender.warn_log.fileName=/tmp/logpipe
+log4j.appender.warn_log.layout=org.apache.log4j.PatternLayout
+log4j.appender.warn_log.layout.ConversionPattern=shibd;shibd_warn.log;${ENV};${USERTOKEN};%d{%Y-%m-%d %H:%M:%S} %p %c %x: %m%n
+log4j.appender.warn_log.threshold=WARN
+
+log4j.appender.tran_log=org.apache.log4j.FileAppender
+log4j.appender.tran_log.fileName=/tmp/logpipe
+log4j.appender.tran_log.layout=org.apache.log4j.PatternLayout
+log4j.appender.tran_log.layout.ConversionPattern=shibd;transaction.log;${ENV};${USERTOKEN};%d{%Y-%m-%d %H:%M:%S} %p %c %x: %m%n
+
+log4j.appender.sig_log=org.apache.log4j.FileAppender
+log4j.appender.sig_log.fileName=/tmp/logpipe
+log4j.appender.sig_log.layout=org.apache.log4j.PatternLayout
+log4j.appender.sig_log.layout.ConversionPattern=shibd;signature.log${ENV};${USERTOKEN};%m
diff --git a/comanage-match-internet2-tap/supervisord.conf b/comanage-match-internet2-tap/supervisord.conf
new file mode 100644
index 0000000..e548507
--- /dev/null
+++ b/comanage-match-internet2-tap/supervisord.conf
@@ -0,0 +1,45 @@
+; COmanage Match Docker supervisord configuration
+; 
+; Portions licensed to the University Corporation for Advanced Internet
+; Development, Inc. ("UCAID") under one or more contributor license agreements.
+; See the NOTICE file distributed with this work for additional information
+; regarding copyright ownership.
+; 
+; UCAID licenses this file to you under the Apache License, Version 2.0
+; (the "License"); you may not use this file except in compliance with the
+; License. You may obtain a copy of the License at:
+; 
+; http://www.apache.org/licenses/LICENSE-2.0
+; 
+; Unless required by applicable law or agreed to in writing, software
+; distributed under the License is distributed on an "AS IS" BASIS,
+; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+; See the License for the specific language governing permissions and
+; limitations under the License.
+
+[supervisord]
+logfile=/tmp/logsuperd
+logfile_maxbytes=0
+nodaemon=true
+user=root
+
+[program:httpd]
+command=/usr/local/bin/docker-comanage-entrypoint
+stdout_logfile=/tmp/loghttpd
+stdout_logfile_maxbytes=0
+stderr_logfile=/tmp/loghttpd
+stderr_logfile_maxbytes=0
+
+[program:shibd]
+command=/usr/local/bin/docker-comanage-shibboleth-sp-entrypoint
+stdout_logfile=/tmp/logshibd
+stdout_logfile_maxbytes=0
+stderr_logfile=/tmp/logshibd
+stderr_logfile_maxbytes=0
+
+[program:crond]
+command=/usr/sbin/crond -i -m off -n
+stdout_logfile=/tmp/logcrond
+stdout_logfile_maxbytes=0
+stderr_logfile=/tmp/logcrond
+stderr_logfile_maxbytes=0
diff --git a/comanage-match-postgres/.dockerignore b/comanage-match-postgres/.dockerignore
new file mode 100644
index 0000000..b43bf86
--- /dev/null
+++ b/comanage-match-postgres/.dockerignore
@@ -0,0 +1 @@
+README.md
diff --git a/comanage-match-postgres/Dockerfile b/comanage-match-postgres/Dockerfile
new file mode 100644
index 0000000..cf4ab2d
--- /dev/null
+++ b/comanage-match-postgres/Dockerfile
@@ -0,0 +1,48 @@
+# COmanage Match Dockerfile for PostgreSQL
+#
+# Portions licensed to the University Corporation for Advanced Internet
+# Development, Inc. ("UCAID") under one or more contributor license agreements.
+# See the NOTICE file distributed with this work for additional information
+# regarding copyright ownership.
+#
+# UCAID licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+FROM postgres:11.3
+#FROM postgres:9.6.13
+
+#RUN apt-get update && apt-get install -y \
+    #         postgresql-contrib-9.6 \
+    #  && apt-get clean
+
+ENV INIT_DIR /docker-entrypoint-initdb.d
+
+RUN mkdir -p "$INIT_DIR"
+
+COPY init-comanage-match-database.sh "$INIT_DIR/init-comanage-match-database.sh"
+COPY create-pg_hba.conf.sh "$INIT_DIR/create-pg_hba.conf.sh"
+COPY comanage-match-postgres-entrypoint.sh /usr/local/bin/comanage-match-postgres-entrypoint.sh
+
+RUN chmod 0755 "$INIT_DIR/init-comanage-match-database.sh"
+RUN chmod 0755 "$INIT_DIR/create-pg_hba.conf.sh"
+RUN chmod 0755 /usr/local/bin/comanage-match-postgres-entrypoint.sh
+
+ARG COMANAGE_MATCH_POSTGRES_DATABASE
+ARG COMANAGE_MATCH_POSTGRES_USER
+ARG COMANAGE_MATCH_POSTGRES_USER_PASSWORD
+
+ENV COMANAGE_MATCH_POSTGRES_DATABASE ${COMANAGE_MATCH_POSTGRES_DATABASE:-match}
+ENV COMANAGE_MATCH_POSTGRES_USER ${COMANAGE_MATCH_POSTGRES_USER:-match_user}
+ENV COMANAGE_MATCH_POSTGRES_USER_PASSWORD ${COMANAGE_MATCH_POSTGRES_USER_PASSWORD:-}
+
+ENTRYPOINT ["/usr/local/bin/comanage-match-postgres-entrypoint.sh"]
+
+CMD ["postgres"]
diff --git a/comanage-match-postgres/README.md b/comanage-match-postgres/README.md
new file mode 100644
index 0000000..adce0fd
--- /dev/null
+++ b/comanage-match-postgres/README.md
@@ -0,0 +1,178 @@
+<!--
+COmanage Docker documentation
+
+Portions licensed to the University Corporation for Advanced Internet
+Development, Inc. ("UCAID") under one or more contributor license agreements.
+See the NOTICE file distributed with this work for additional information
+regarding copyright ownership.
+
+UCAID licenses this file to you under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with the
+License. You may obtain a copy of the License at:
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+# PostgreSQL for COmanage Match
+
+Intended to build a PostgreSQL image for use with COmanage Match.
+
+## Build Arguments
+
+No arguments are required for building the image.
+
+The following arguments may be supplied during the build:
+
+```
+--build-arg COMANAGE_MATCH_POSTGRES_DATABASE=<name of database to use with COmanage Match>
+--build-arg COMANAGE_MATCH_POSTGRES_USER=<database username>
+--build-arg COMANAGE_MATCH_POSTGRES_USER_PASSWORD=<database password>
+```
+
+## Building
+
+```
+docker build \
+  -t comanage-match-postgres:<tag> .
+```
+
+## Building Example
+
+```
+export COMANAGE_MATCH_POSTGRES_IMAGE_VERSION=1
+TAG="${COMANAGE_MATCH_POSTGRES_IMAGE_VERSION}"
+docker build \
+  -t comanage-match-postgres:$TAG .
+```
+
+## Volumes and Data Persistence
+
+You must provide a volume or bind mount that mounts to `/var/lib/postgresql/data`
+inside the container to persist data saved to the relational database.
+
+## Environment Variables
+
+The image supports the environment variables below and the `_FILE`
+[convention](../docs/comanage-match-common-environment-variables.md):
+
+`POSTGRES_USER`
+
+* Description: superuser
+* Required: yes
+* Default: `postgres`
+* Example: `db_user`
+* Note: Most deployers use the default.
+
+`POSTGRES_PASSWORD`
+
+* Description: password for superuser
+* Required: no
+* Default: none
+* Example: `l7cX28O3mt03y41EndjM`
+* Note: If you do not set a password for the superuser then
+any client with access to the container may connect to the database.
+
+`COMANAGE_MATCH_POSTGRES_DATABASE`
+
+* Description: COmanage Registry database
+* Required: yes
+* Default: `registry`
+* Example: `comanage_registry`
+
+`COMANAGE_MATCH_POSTGRES_USER`
+
+* Description: COmanage Registry database user
+* Required: yes
+* Default: `registry_user`
+* Example: `comanage_registry_user`
+
+`COMANAGE_MATCH_POSTGRES_USER_PASSWORD`
+
+* Description: password for database user
+* Required: no
+* Default: none
+* Example: `5Aw9SzS4xqYi7daHw57c`
+* Note: If you do not set a password for the COmanage Registry user then
+any client with access to the container may connect to the database.
+
+## Authentication
+
+If you do not set a password for the superuser or the COmanage Match user then
+any client with access to the container may connect to the database.
+
+## Ports
+
+The image listens for traffic on port 5432.
+
+## Running
+
+See other documentation in this repository for details on how to orchestrate
+running this image with other images using an orchestration tool like
+Docker Compose, Docker Swarm, or Kubernetes.
+
+To run this image:
+
+```
+docker run -d \
+  --name comanage-match-database \
+  -v /tmp/postgres-data:/var/lib/postgresql/data \
+  -e POSTGRES_USER=postgres \
+  -e POSTGRES_PASSWORD=superuser_password \
+  -e COMANAGE_MATCH_POSTGRES_DATABASE=registry \
+  -e COMANAGE_MATCH_POSTGRES_USER=match_user \
+  -e COMANAGE_MATCH_POSTGRES_USER_PASSWORD=password \
+  comanage-match-postgres
+```
+
+## Logging
+
+PostgreSQL logs to the stdout and stderr of the container.
+
+## Connecting
+
+After breaking into the container you may connect to the
+COmanage Match database as the COmanage Match database
+user by running
+
+```
+psql -h 127.0.0.1 ${COMANAGE_MATCH_POSTGRES_DATABASE} ${COMANAGE_MATCH_POSTGRES_USER}
+```
+
+For example
+
+```
+# psql -h 127.0.0.1 match match_user
+Password for user match_user: 
+psql (11.0.0)
+Type "help" for help.
+
+match=>
+```
+
+## Backups
+
+A common strategy for backing up the database is to run another temporary
+container that executes the `pg_dump` command. You need to be sure that the
+temporary container and the database container use the same network.
+
+An example is
+
+```
+docker run \
+    -it \
+    --rm \
+    --network temp_default \
+    comanage-match-postgres \
+    pg_dump \
+        -h comanage-match-database \
+        -U match_user \
+        match
+```
+
+The output from the `pg_dump` command is sent to the stdout of the temporary
+container and may be redirected to a file.
diff --git a/comanage-match-postgres/comanage-match-postgres-entrypoint.sh b/comanage-match-postgres/comanage-match-postgres-entrypoint.sh
new file mode 100755
index 0000000..2459571
--- /dev/null
+++ b/comanage-match-postgres/comanage-match-postgres-entrypoint.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+
+# COmanage Match PostgreSQL Dockerfile entrypoint
+#
+# Portions licensed to the University Corporation for Advanced Internet
+# Development, Inc. ("UCAID") under one or more contributor license agreements.
+# See the NOTICE file distributed with this work for additional information
+# regarding copyright ownership.
+#
+# UCAID licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+if [[ -f "${COMANAGE_MATCH_POSTGRES_DATABASE_FILE}" ]]; then
+    COMANAGE_MATCH_POSTGRES_DATABASE=`cat ${COMANAGE_MATCH_POSTGRES_DATABASE_FILE}`
+    export COMANAGE_MATCH_POSTGRES_DATABASE
+fi
+
+if [[ -f "${COMANAGE_MATCH_POSTGRES_USER_FILE}" ]]; then
+    COMANAGE_MATCH_POSTGRES_USER=`cat ${COMANAGE_MATCH_POSTGRES_USER_FILE}`
+    export COMANAGE_MATCH_POSTGRES_USER
+fi
+
+if [[ -f "${COMANAGE_MATCH_POSTGRES_USER_PASSWORD_FILE}" ]]; then
+    COMANAGE_MATCH_POSTGRES_USER_PASSWORD=`cat ${COMANAGE_MATCH_POSTGRES_USER_PASSWORD_FILE}`
+    export COMANAGE_MATCH_POSTGRES_USER_PASSWORD
+fi
+
+exec "/docker-entrypoint.sh" "$@"
diff --git a/comanage-match-postgres/create-pg_hba.conf.sh b/comanage-match-postgres/create-pg_hba.conf.sh
new file mode 100755
index 0000000..e21b7e4
--- /dev/null
+++ b/comanage-match-postgres/create-pg_hba.conf.sh
@@ -0,0 +1,55 @@
+#!/bin/bash 
+
+# COmanage Registry PostgreSQL pg_hba.conf creation script
+#
+# Portions licensed to the University Corporation for Advanced Internet
+# Development, Inc. ("UCAID") under one or more contributor license agreements.
+# See the NOTICE file distributed with this work for additional information
+# regarding copyright ownership.
+#
+# UCAID licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set -e
+
+# Measure the existing pg_hba.conf file to see if it is the default.
+# The default version written will depend on whether or not passwords
+# have been injected.
+CHECKSUM=`md5sum /var/lib/postgresql/data/pg_hba.conf | awk '{print $1}'`
+if [ "$CHECKSUM" = "6306f443e155072ce8b28d0936704b64" ]
+then
+    PG_HBA_DEFAULT="1"
+else
+    PG_HBA_DEFAULT="0"
+fi
+
+# If the pg_hba.conf file is the default overwrite a more restrictive
+# version.
+
+if [ "$PG_HBA_DEFAULT" = "1" ]
+then
+    # If a password has been injected require it, otherwise just use samenet trust.
+    if [ -n "$COMANAGE_MATCH_POSTGRES_USER_PASSWORD" ] 
+    then
+        cat > /var/lib/postgresql/data/pg_hba.conf <<EOF
+local all postgres peer
+host $COMANAGE_MATCH_POSTGRES_DATABASE $COMANAGE_MATCH_POSTGRES_USER 127.0.0.1/32 md5
+host $COMANAGE_MATCH_POSTGRES_DATABASE $COMANAGE_MATCH_POSTGRES_USER samenet md5
+EOF
+
+    else
+        cat > /var/lib/postgresql/data/pg_hba.conf <<EOF
+local all postgres peer
+host $COMANAGE_MATCH_POSTGRES_DATABASE $COMANAGE_MATCH_POSTGRES_USER samenet trust
+EOF
+    fi
+fi
diff --git a/comanage-match-postgres/init-comanage-match-database.sh b/comanage-match-postgres/init-comanage-match-database.sh
new file mode 100644
index 0000000..86caa63
--- /dev/null
+++ b/comanage-match-postgres/init-comanage-match-database.sh
@@ -0,0 +1,43 @@
+#!/bin/bash -x
+
+# COmanage Registry PostgreSQL entrypoint
+#
+# Portions licensed to the University Corporation for Advanced Internet
+# Development, Inc. ("UCAID") under one or more contributor license agreements.
+# See the NOTICE file distributed with this work for additional information
+# regarding copyright ownership.
+#
+# UCAID licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set -e
+
+if [ -n "$COMANAGE_MATCH_POSTGRES_USER_PASSWORD" ]
+then
+    psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL
+    CREATE USER $COMANAGE_MATCH_POSTGRES_USER WITH ENCRYPTED PASSWORD '$COMANAGE_MATCH_POSTGRES_USER_PASSWORD';
+    CREATE DATABASE $COMANAGE_MATCH_POSTGRES_DATABASE;
+    GRANT ALL PRIVILEGES ON DATABASE $COMANAGE_MATCH_POSTGRES_DATABASE TO $COMANAGE_MATCH_POSTGRES_USER;
+EOSQL
+
+else
+    psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL
+    CREATE USER $COMANAGE_MATCH_POSTGRES_USER;
+    CREATE DATABASE $COMANAGE_MATCH_POSTGRES_DATABASE;
+    GRANT ALL PRIVILEGES ON DATABASE $COMANAGE_MATCH_POSTGRES_DATABASE TO $COMANAGE_MATCH_POSTGRES_USER;
+EOSQL
+
+psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" "$COMANAGE_MATCH_POSTGRES_DATABASE" <<-EOSQL
+CREATE EXTENSION fuzzystrmatch;
+EOSQL
+
+fi
diff --git a/comanage-match-shibboleth-sp/.dockerignore b/comanage-match-shibboleth-sp/.dockerignore
new file mode 100644
index 0000000..b43bf86
--- /dev/null
+++ b/comanage-match-shibboleth-sp/.dockerignore
@@ -0,0 +1 @@
+README.md
diff --git a/comanage-match-shibboleth-sp/000-comanage.conf b/comanage-match-shibboleth-sp/000-comanage.conf
new file mode 100644
index 0000000..267117e
--- /dev/null
+++ b/comanage-match-shibboleth-sp/000-comanage.conf
@@ -0,0 +1,53 @@
+# COmanage Match Apache HTTP Server configuration
+#
+# Portions licensed to the University Corporation for Advanced Internet
+# Development, Inc. ("UCAID") under one or more contributor license agreements.
+# See the NOTICE file distributed with this work for additional information
+# regarding copyright ownership.
+#
+# UCAID licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+Include apache-include-virtual-host-port80-redirect
+
+<VirtualHost *:443>
+
+Include apache-include-virtual-host-port443-base
+
+SSLCertificateFile /etc/apache2/cert.pem
+SSLCertificateKeyFile /etc/apache2/privkey.pem
+
+ErrorLog ${APACHE_LOG_DIR}/error.log
+CustomLog ${APACHE_LOG_DIR}/access.log combined
+
+Include apache-include-directory-match
+
+<Location "/Shibboleth.sso">
+SetHandler shib
+</Location>
+
+<Directory /var/www/html/match/auth/login>
+AuthType shibboleth
+ShibRequestSetting requireSession 1
+Require valid-user
+</Directory>
+
+<Location />
+AuthType shibboleth
+Require shibboleth
+</Location>
+
+RewriteEngine On
+RewriteCond %{QUERY_STRING} !after_redirect
+RewriteRule ^/match/auth/logout.* https://%{HTTP_HOST}/Shibboleth.sso/Logout?return=https://%{HTTP_HOST}/match/auth/logout/?after_redirect [L,R]
+
+</VirtualHost>
diff --git a/comanage-match-shibboleth-sp/Dockerfile b/comanage-match-shibboleth-sp/Dockerfile
new file mode 100644
index 0000000..7dbaf0c
--- /dev/null
+++ b/comanage-match-shibboleth-sp/Dockerfile
@@ -0,0 +1,73 @@
+# COmanage Registry Dockerfile
+#
+# Portions licensed to the University Corporation for Advanced Internet
+# Development, Inc. ("UCAID") under one or more contributor license agreements.
+# See the NOTICE file distributed with this work for additional information
+# regarding copyright ownership.
+#
+# UCAID licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+ARG COMANAGE_MATCH_VERSION=develop
+ARG COMANAGE_MATCH_BASE_IMAGE_VERSION=1
+ARG COMANAGE_SHIBBOLETH_SP_VERSION="3.0.4"
+ARG COMANAGE_SHIBBOLETH_SP_BASE_IMAGE_VERSION=1
+
+FROM comanage-shibboleth-sp-base:${COMANAGE_SHIBBOLETH_SP_VERSION}-${COMANAGE_SHIBBOLETH_SP_BASE_IMAGE_VERSION} AS shib-base
+
+FROM comanage-match-base:${COMANAGE_MATCH_VERSION}-${COMANAGE_MATCH_BASE_IMAGE_VERSION} AS comanage
+
+ARG COMANAGE_MATCH_BASE_IMAGE_VERSION
+ENV COMANAGE_MATCH_BASE_IMAGE_VERSION ${COMANAGE_MATCH_BASE_IMAGE_VERSION}
+LABEL comanage_match_base_image_version=${COMANAGE_MATCH_BASE_IMAGE_VERSION}
+
+ARG COMANAGE_SHIBBOLETH_SP_VERSION
+ENV COMANAGE_SHIBBOLETH_SP_VERSION ${COMANAGE_SHIBBOLETH_SP_VERSION}
+LABEL comanage_shibboleth_sp_version=${COMANAGE_SHIBBOLETH_SP_VERSION}
+
+ARG COMANAGE_SHIBBOLETH_SP_BASE_IMAGE_VERSION
+ENV COMANAGE_SHIBBOLETH_SP_BASE_IMAGE_VERSION ${COMANAGE_SHIBBOLETH_SP_BASE_IMAGE_VERSION}
+LABEL comanage_shibboleth_sp_base_image_version ${COMANAGE_SHIBBOLETH_SP_BASE_IMAGE_VERSION}
+
+RUN apt-get install -y --no-install-recommends supervisor \
+      && mkdir -p /var/log/supervisor
+
+COPY --from=shib-base /opt/shibboleth-sp /opt/shibboleth-sp/
+COPY --from=shib-base /opt/shibboleth-sp/etc/shibboleth/shib2.load /etc/apache2/mods-available/
+
+RUN /usr/sbin/useradd --system _shibd \
+      && mkdir -p /var/run/shibboleth \
+      && chown _shibd:_shibd /var/run/shibboleth \
+      && chown -R _shibd:_shibd /opt/shibboleth-sp/var \
+      && cp -a /opt/shibboleth-sp/etc/shibboleth /etc/shibboleth \
+      && rm -f /etc/shibboleth/shibboleth2.xml \
+      && chown _shibd:_shibd /etc/shibboleth/sp-signing-cert.pem \
+      && chown _shibd:_shibd /etc/shibboleth/sp-signing-key.pem \
+      && chown _shibd:_shibd /etc/shibboleth/sp-encrypt-cert.pem \
+      && chown _shibd:_shibd /etc/shibboleth/sp-encrypt-key.pem \
+      && cd /opt/shibboleth-sp/etc \
+      && rm -rf shibboleth \
+      && ln -s /etc/shibboleth shibboleth \
+      && a2enmod shib2
+
+COPY --chown=_shibd:_shibd shibd.logger /etc/shibboleth/shibd.logger
+COPY --chown=_shibd:_shibd native.logger /etc/shibboleth/native.logger
+
+COPY supervisord.conf /usr/local/etc/supervisord.conf
+
+COPY 000-comanage.conf /etc/apache2/sites-available/
+RUN a2ensite 000-comanage
+
+COPY docker-comanage-shibboleth-sp-entrypoint /usr/local/bin/
+
+VOLUME /etc/shibboleth
+
+ENTRYPOINT ["/usr/bin/supervisord", "-c", "/usr/local/etc/supervisord.conf"]
diff --git a/comanage-match-shibboleth-sp/README.md b/comanage-match-shibboleth-sp/README.md
new file mode 100644
index 0000000..226ff4d
--- /dev/null
+++ b/comanage-match-shibboleth-sp/README.md
@@ -0,0 +1,135 @@
+<!--
+COmanage Docker documentation
+
+Portions licensed to the University Corporation for Advanced Internet
+Development, Inc. ("UCAID") under one or more contributor license agreements.
+See the NOTICE file distributed with this work for additional information
+regarding copyright ownership.
+
+UCAID licenses this file to you under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with the
+License. You may obtain a copy of the License at:
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+# COmanage Match Shibboleth
+
+Intended to build a COmanage Match image using the Shibboleth Native SP
+for Apache HTTP Server (Shibboleth) as the authentication mechanism. 
+
+## Build Arguments
+
+Building the image requires the following build arguments:
+
+```
+--build-arg COMANAGE_MATCH_VERSION=<version number>
+--build-arg COMANAGE_MATCH_BASE_IMAGE_VERSION=<base image version number>
+--build-arg COMANAGE_SHIBBOLETH_SP_VERSION=<Shibboleth SP version number>
+--build-arg COMANAGE_SHIBBOLETH_SP_BASE_IMAGE_VERSION=<Shibboleth SP base image version number>
+```
+
+## Build Requirements
+
+This image uses a [multi-stage build](https://docs.docker.com/develop/develop-images/multistage-build/).
+It requires that the [COmanage Match base image](../comanage-match-base/README.md) 
+and [Shibboleth SP base image](../../comanage-shibboleth-sp-base/README.md) be built first.
+
+## Building
+
+```
+docker build \
+  --build-arg COMANAGE_MATCH_VERSION=<COmanage Match version number> \
+  --build-arg COMANAGE_MATCH_BASE_IMAGE_VERSION=<base image version number> \
+  --build-arg COMANAGE_SHIBBOLETH_SP_VERSION=<Shibboleth SP version number> \
+  --build-arg COMANAGE_SHIBBOLETH_SP_BASE_IMAGE_VERSION=<Shibboleth SP base image version number> \
+  -t comanage-match:<tag> .
+```
+
+## Building Example
+
+```
+export COMANAGE_MATCH_VERSION=1.0.0
+export COMANAGE_MATCH_BASE_IMAGE_VERSION=1
+export COMANAGE_SHIBBOLETH_SP_VERSION=3.0.4
+export COMANAGE_SHIBBOLETH_SP_BASE_IMAGE_VERSION=1
+export COMANAGE_MATCH_SHIBBOLETH_SP_IMAGE_VERSION=1
+TAG="${COMANAGE_MATCH_VERSION}-shibboleth-sp-${COMANAGE_MATCH_SHIBBOLETH_SP_IMAGE_VERSION}"
+docker build \
+  --build-arg COMANAGE_MATCH_VERSION=${COMANAGE_MATCH_VERSION} \
+  --build-arg COMANAGE_MATCH_BASE_IMAGE_VERSION=${COMANAGE_MATCH_BASE_IMAGE_VERSION} \
+  --build-arg COMANAGE_SHIBBOLETH_SP_VERSION=${COMANAGE_SHIBBOLETH_SP_VERSION} \
+  --build-arg COMANAGE_SHIBBOLETH_SP_BASE_IMAGE_VERSION=${COMANAGE_SHIBBOLETH_SP_BASE_IMAGE_VERSION} \
+  -t comanage-match:$TAG .
+```
+
+## Volumes and Data Persistence
+
+See [COmanage Match Volumes and Data Persistence](../docs/volumes-and-data-persistence.md).
+
+
+## Environment Variables
+
+See the [list of environment variables common to all images](../docs/comanage-match-common-environment-variables.md)
+including this image.
+
+See also the
+[list of environment variables common to all images using Shibboleth](../../docs/comanage-common-shibboleth-environment-variables.md).
+
+## Authentication
+
+This image supports using the Shibboleth Native SP for Apache HTTP Server (Shibboleth) as the
+authentication mechanism. Deployers should configure Shibboleth so that the desired
+asserted user attribute is written into `REMOTE_USER`.
+
+## Ports
+
+The image listens for web traffic on ports 80 and 443. All requests
+on port 80 are redirected to port 443.
+
+## Running
+
+See other documentation in this repository for details on how to orchestrate
+running this image with other images using an orchestration tool like
+Docker Compose, Docker Swarm, or Kubernetes.
+
+To run this image:
+
+```
+docker run -d \
+  --name comanage-match \
+  -e COMANAGE_MATCH_ADMIN_USERNAME=julia.janseen@my.org \
+  -e SHIBBOLETH_SP_ENTITY_ID=https://myapp.my.org/shibboleth/sp \
+  -e SHIBBOLETH_SP_METADATA_PROVIDER_XML_FILE=/etc/shibboleth/my-org-metadata.xml \
+  -v /opt/comanage-match-local:/srv/comanage-match/local \
+  -v /etc/shibboleth/sp-encrypt-cert.pem:/etc/shibboleth/sp-encrypt-cert.pem \
+  -v /etc/shibboleth/sp-encrypt-key.pem:/etc/shibboleth/sp-encrypt-key.pem \
+  -v /etc/shibboleth/my-org-metadata.xml:/etc/shibboleth/my-org-metadata.xml \
+  -p 80:80 \
+  -p 443:443 \
+  comanage-match:1.0.0-shibboleth-sp-1
+```
+
+## Logging
+
+Apache HTTP Server, COmanage Match, Shibboleth, and supervisord all log to the stdout and
+stderr of the container.
+
+## HTTPS Configuration
+
+See the section on environment variables and the `HTTPS_CERT_FILE` and
+`HTTPS_PRIVKEY_FILE` variables.
+
+Additionally you may bind mount or COPY in an X.509 certificate file (containing the CA signing certificate(s), if any)
+and associated private key file. For example
+
+```
+COPY cert.pem /etc/apache2/cert.pem
+COPY privkey.pem /etc/apache2/privkey.pem
+```
diff --git a/comanage-match-shibboleth-sp/docker-comanage-shibboleth-sp-entrypoint b/comanage-match-shibboleth-sp/docker-comanage-shibboleth-sp-entrypoint
new file mode 100755
index 0000000..ac62496
--- /dev/null
+++ b/comanage-match-shibboleth-sp/docker-comanage-shibboleth-sp-entrypoint
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+# COmanage Shibboleth SP Dockerfile entrypoint
+#
+# Portions licensed to the University Corporation for Advanced Internet
+# Development, Inc. ("UCAID") under one or more contributor license agreements.
+# See the NOTICE file distributed with this work for additional information
+# regarding copyright ownership.
+#
+# UCAID licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with the
+# License. You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+source /usr/local/lib/comanage_shibboleth_sp_utils.sh
+
+comanage_shibboleth_sp_utils::exec_shibboleth_sp_daemon
diff --git a/comanage-match-shibboleth-sp/native.logger b/comanage-match-shibboleth-sp/native.logger
new file mode 100644
index 0000000..f8300c8
--- /dev/null
+++ b/comanage-match-shibboleth-sp/native.logger
@@ -0,0 +1,32 @@
+# set overall behavior
+log4j.rootCategory=INFO, native_log
+
+# fairly verbose for DEBUG, so generally leave at WARN/INFO
+log4j.category.XMLTooling.XMLObject=WARN
+log4j.category.XMLTooling.KeyInfoResolver=WARN
+log4j.category.Shibboleth.IPRange=WARN
+log4j.category.Shibboleth.PropertySet=WARN
+
+# raise for low-level tracing of SOAP client HTTP/SSL behavior
+log4j.category.XMLTooling.libcurl=WARN
+
+# useful categories to tune independently:
+#
+# tracing of SAML messages and security policies
+#log4j.category.OpenSAML.MessageDecoder=DEBUG
+#log4j.category.OpenSAML.MessageEncoder=DEBUG
+#log4j.category.OpenSAML.SecurityPolicyRule=DEBUG
+# interprocess message remoting
+#log4j.category.Shibboleth.Listener=DEBUG
+# mapping of requests to applicationId
+#log4j.category.Shibboleth.RequestMapper=DEBUG
+# high level session cache operations
+#log4j.category.Shibboleth.SessionCache=DEBUG
+# persistent storage and caching
+#log4j.category.XMLTooling.StorageService=DEBUG
+
+# define the appender
+
+log4j.appender.native_log=org.apache.log4j.ConsoleAppender
+log4j.appender.native_log.layout=org.apache.log4j.PatternLayout
+log4j.appender.native_log.layout.ConversionPattern=native_log %p %c %x: %m%n
diff --git a/comanage-match-shibboleth-sp/shibd.logger b/comanage-match-shibboleth-sp/shibd.logger
new file mode 100644
index 0000000..5fd332b
--- /dev/null
+++ b/comanage-match-shibboleth-sp/shibd.logger
@@ -0,0 +1,57 @@
+# set overall behavior
+log4j.rootCategory=INFO, shibd_log
+
+# fairly verbose for DEBUG, so generally leave at INFO
+log4j.category.XMLTooling.XMLObject=INFO
+log4j.category.XMLTooling.KeyInfoResolver=INFO
+log4j.category.Shibboleth.IPRange=INFO
+log4j.category.Shibboleth.PropertySet=INFO
+
+# raise for low-level tracing of SOAP client HTTP/SSL behavior
+log4j.category.XMLTooling.libcurl=INFO
+
+# useful categories to tune independently:
+#
+# tracing of SAML messages and security policies
+#log4j.category.OpenSAML.MessageDecoder=DEBUG
+#log4j.category.OpenSAML.MessageEncoder=DEBUG
+#log4j.category.OpenSAML.SecurityPolicyRule=DEBUG
+#log4j.category.XMLTooling.SOAPClient=DEBUG
+# interprocess message remoting
+#log4j.category.Shibboleth.Listener=DEBUG
+# mapping of requests to applicationId
+#log4j.category.Shibboleth.RequestMapper=DEBUG
+# high level session cache operations
+#log4j.category.Shibboleth.SessionCache=DEBUG
+# persistent storage and caching
+#log4j.category.XMLTooling.StorageService=DEBUG
+
+# logs XML being signed or verified if set to DEBUG
+log4j.category.XMLTooling.Signature.Debugger=INFO, sig_log
+log4j.additivity.XMLTooling.Signature.Debugger=false
+log4j.ownAppenders.XMLTooling.Signature.Debugger=true
+
+# the tran log blocks the "default" appender(s) at runtime
+# Level should be left at INFO for this category
+log4j.category.Shibboleth-TRANSACTION=INFO, tran_log
+log4j.additivity.Shibboleth-TRANSACTION=false
+log4j.ownAppenders.Shibboleth-TRANSACTION=true
+
+# uncomment to suppress particular event types
+#log4j.category.Shibboleth-TRANSACTION.AuthnRequest=WARN
+#log4j.category.Shibboleth-TRANSACTION.Login=WARN
+#log4j.category.Shibboleth-TRANSACTION.Logout=WARN
+
+# define the appenders
+
+log4j.appender.shibd_log=org.apache.log4j.ConsoleAppender
+log4j.appender.shibd_log.layout=org.apache.log4j.PatternLayout
+log4j.appender.shibd_log.layout.ConversionPattern=shibd_log %d{%Y-%m-%d %H:%M:%S} %p %c %x: %m%n
+
+log4j.appender.tran_log=org.apache.log4j.ConsoleAppender
+log4j.appender.tran_log.layout=org.apache.log4j.PatternLayout
+log4j.appender.tran_log.layout.ConversionPattern=tran_log %d{%Y-%m-%d %H:%M:%S}|%c|%m%n
+
+log4j.appender.sig_log=org.apache.log4j.ConsoleAppender
+log4j.appender.sig_log.layout=org.apache.log4j.PatternLayout
+log4j.appender.sig_log.layout.ConversionPattern=sig_log %m
diff --git a/comanage-match-shibboleth-sp/supervisord.conf b/comanage-match-shibboleth-sp/supervisord.conf
new file mode 100644
index 0000000..47083c6
--- /dev/null
+++ b/comanage-match-shibboleth-sp/supervisord.conf
@@ -0,0 +1,36 @@
+; COmanage Docker supervisord configuration
+; 
+; Portions licensed to the University Corporation for Advanced Internet
+; Development, Inc. ("UCAID") under one or more contributor license agreements.
+; See the NOTICE file distributed with this work for additional information
+; regarding copyright ownership.
+; 
+; UCAID licenses this file to you under the Apache License, Version 2.0
+; (the "License"); you may not use this file except in compliance with the
+; License. You may obtain a copy of the License at:
+; 
+; http://www.apache.org/licenses/LICENSE-2.0
+; 
+; Unless required by applicable law or agreed to in writing, software
+; distributed under the License is distributed on an "AS IS" BASIS,
+; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+; See the License for the specific language governing permissions and
+; limitations under the License.
+
+[supervisord]
+nodaemon=true
+user=root
+
+[program:apache2]
+command=/usr/local/bin/docker-comanage-match-entrypoint apache2-foreground
+stdout_logfile=/dev/stdout
+stdout_logfile_maxbytes=0
+stderr_logfile=/dev/stderr
+stderr_logfile_maxbytes=0
+
+[program:shibd]
+command=/usr/local/bin/docker-comanage-shibboleth-sp-entrypoint
+stdout_logfile=/dev/stdout
+stdout_logfile_maxbytes=0
+stderr_logfile=/dev/stderr
+stderr_logfile_maxbytes=0
diff --git a/docs/comanage-match-common-environment-variables.md b/docs/comanage-match-common-environment-variables.md
new file mode 100644
index 0000000..399eeb3
--- /dev/null
+++ b/docs/comanage-match-common-environment-variables.md
@@ -0,0 +1,135 @@
+<!--
+COmanage Docker documentation
+
+Portions licensed to the University Corporation for Advanced Internet
+Development, Inc. ("UCAID") under one or more contributor license agreements.
+See the NOTICE file distributed with this work for additional information
+regarding copyright ownership.
+
+UCAID licenses this file to you under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with the
+License. You may obtain a copy of the License at:
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+# Environment Variables Common to All Images
+
+The environment variables detailed below apply to all COmanage
+Match images in this repository.
+
+## Using Files to Inject Secrets
+
+The COmanage Match images support the convention of an associated
+environment variable ending with ```_FILE``` to indicate a path
+relative to the container from which the value for an environment
+variable should be read.
+
+For example if the environment variable ```COMANAGE_MATCH_DATABASE_USER_PASSWORD_FILE```
+exists and its value is the path to a readable file, then the contents of the
+file will be read into the environment variable ```COMANAGE_MATCH_DATABASE_USER_PASSWORD```.
+
+If both an environment variable and the associated ```_FILE``` environment variable
+are defined the associated ```_FILE``` environment variable takes precedence, 
+provided that the file it points to exists and is readable.
+
+## Environment Variables
+
+```COMANAGE_MATCH_ADMIN_USERNAME```
+
+* Description: Username name for first platform administrator
+* Required: yes
+* Default: match.admin
+* Example: julia.janseen@my.org
+* Note: \[[1](#note01)\]
+
+```COMANAGE_MATCH_DATASOURCE```
+
+* Description: database type
+* Required: yes
+* Default: Database/Postgres
+* Example: Database/Postgres
+* Note: \[[2](#note02)\]
+
+```COMANAGE_MATCH_DATABASE```
+
+* Description: database name
+* Required: yes
+* Default: match
+* Example: comanage_match
+* Note: \[[2](#note02)\]
+
+```COMANAGE_MATCH_DATABASE_HOST```
+
+* Description: database server host
+* Required: yes
+* Default: comanage-match-database
+* Example: database-server.my.org
+* Note: \[[2](#note02)\]
+
+```COMANAGE_MATCH_DATABASE_USER```
+
+* Description: database username
+* Required: yes
+* Default: match_user
+* Example: comanage-user
+* Note: \[[2](#note02)\]
+
+```COMANAGE_MATCH_DATABASE_USER_PASSWORD```
+
+* Description: database user password
+* Required: yes
+* Default: password
+* Example: O5Yhtt6TLOxNjo93fmB9
+* Note: \[[2](#note02)\]
+
+```COMANAGE_MATCH_SECURITY_SALT```
+
+* Description: Security salt used when hashing. Must be 40 or more characters from the set [0-9a-zA-Z].
+* Required: no
+* Default: automatically generated if not provided
+* Example: VuUq2mnXC0Cco8uKcjO1rDdP2lVC3lgP970QP2XY
+* Note: If present the environment variable is read the first time the container is
+started and written to the persistent volume (or bind mount) in the 
+configuration file ```security.salt```. Later changes to the environment
+variable are *not* reflected in the file which must be
+edited directly.
+
+```COMANAGE_MATCH_VIRTUAL_HOST_FQDN```
+
+* Description: Apache HTTP Server virtual host name
+* Required: no
+* Default: Obtained from inspecting HTTPS x509 certificate file if present, otherwise "unknown"
+* Example: match.my.org
+
+```HTTPS_CERT_FILE```
+
+* Description: path to file containing x509 certificate for HTTPS
+* Required: no
+* Default: automatically generated self-signed certificate
+* Example: /run/secrets/https_cert_file
+* Note: The path is relative to the running container.
+
+```HTTPS_PRIVKEY_FILE```
+
+* Description: path to file containing x509 private key for HTTPS
+* Required: no
+* Default: automatically generated private key
+* Example: /run/secrets/https_privkey_file
+* Note: The path is relative to the running container.
+
+\[<a name="note01">1</a>\]: The environment variable is read the first time the container is
+started and saved to the COmanage Match database.  Later changes to the environment
+variable are *not* reflected in the database state.
+
+\[<a name="note02">2</a>\]: The environment variable is read the first time the container is
+started and written to the persistent volume (or bind mount) in the 
+configuration file ```database.php```. Later changes to the environment
+variable are *not* reflected in the configuration file which must be
+edited directly.
diff --git a/docs/evaluation.md b/docs/evaluation.md
new file mode 100644
index 0000000..6df8849
--- /dev/null
+++ b/docs/evaluation.md
@@ -0,0 +1,131 @@
+<!--
+COmanage Docker documentation
+
+Portions licensed to the University Corporation for Advanced Internet
+Development, Inc. ("UCAID") under one or more contributor license agreements.
+See the NOTICE file distributed with this work for additional information
+regarding copyright ownership.
+
+UCAID licenses this file to you under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with the
+License. You may obtain a copy of the License at:
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+# Evaluating COmanage Match using Docker
+
+Follow these steps to build and run a simple deployment of COmanage Match
+suitable for evaluation purposes.
+
+* Install Docker. These instructions require version 17.05 or higher.
+
+* Install [Docker Compose](https://docs.docker.com/compose/). These instructions require 
+version 1.13.0 or higher.
+
+* Clone this repository:
+
+```
+git clone https://github.internet2.edu/COmanage/docker.git
+cd docker/comanage-match
+```
+
+* Define the shell variable `COMANAGE_MATCH_VERSION` to be the version
+of COmanage Match you want to deploy. See the
+[COmanage Match Release History](https://spaces.internet2.edu/display/COmanage/Home)
+wiki page for the list of releases. We recommend using the latest release.
+
+Here is an example (but please check the wiki page for the latest release number):
+
+```
+export COMANAGE_MATCH_VERSION=1.0.0
+```
+
+* Build the base COmanage Match image:
+
+```
+pushd comanage-match-base
+docker build \
+    --build-arg COMANAGE_MATCH_VERSION=${COMANAGE_MATCH_VERSION} \
+    -t comanage-match-base:${COMANAGE_MATCH_VERSION}-1 .
+popd
+```
+
+* Build an image for COmanage Match that uses basic authentication:
+
+```
+pushd comanage-match-basic-auth
+docker build \
+    --build-arg COMANAGE_MATCH_VERSION=${COMANAGE_MATCH_VERSION} \
+    -t comanage-match:${COMANAGE_MATCH_VERSION}-basic-auth .
+popd
+```
+
+* Build a local image of PostgreSQL for COmanage Match:
+
+```
+pushd comanage-match-postgres
+docker build -t comanage-match-postgres .
+popd
+```
+
+* Create a docker-compose.yml file:
+
+```
+version: '3.1'
+
+services:
+
+    comanage-match-database:
+        image: comanage-match-postgres
+
+    comanage-match:
+        image: "comanage-match:${COMANAGE_MATCH_VERSION}-basic-auth"
+        ports:
+            - "80:80"
+            - "443:443"
+```
+
+* Start the services:
+```
+docker-compose up -d
+```
+
+* Browse to port 443 on the host, for example `https://localhost/`. You will have to
+  click through the warning from your browser about the self-signed certificate used
+  for HTTPS.
+
+* Click `Login` and when prompted enter `match.admin` as the username and `password`
+for the password. 
+
+* Visit the [COmanage wiki](https://spaces.at.internet2.edu/display/COmanage/Match+Platform+Configuration)
+to learn how to create your first Matchgrid and begin using
+the platform.
+
+* To stop the services:
+```
+docker-compose stop
+```
+
+* To remove the containers and networks:
+```
+docker-compose down
+```
+
+### Important Notes
+The instructions above are *not suitable for a production deployment* for two reasons:
+
+1. The deployed services use default and easily guessed passwords.
+2. No data is persisted. When the containers are destroyed so is your data.
+
+## Next Steps
+To evolve your COmanage Match deployment examine the documentation
+in the [docs directory](./README.md).
+
+
diff --git a/docs/shibboleth-sp-postgresql.md b/docs/shibboleth-sp-postgresql.md
new file mode 100644
index 0000000..fb1f145
--- /dev/null
+++ b/docs/shibboleth-sp-postgresql.md
@@ -0,0 +1,298 @@
+<!--
+COmanage Docker documentation
+
+Portions licensed to the University Corporation for Advanced Internet
+Development, Inc. ("UCAID") under one or more contributor license agreements.
+See the NOTICE file distributed with this work for additional information
+regarding copyright ownership.
+
+UCAID licenses this file to you under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with the
+License. You may obtain a copy of the License at:
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+# COmanage Match with Shibboleth SP and PostgreSQL
+
+Follow these steps to build and run COmanage Match
+using the Shibboleth SP for authentication and PostgreSQL
+as the relational database.
+
+* Install Docker. These instructions require version 17.05 or higher.
+
+* Clone this repository:
+
+```
+git clone https://github.internet2.edu/COmanage/docker
+cd docker
+```
+
+* Define the shell variable `COMANAGE_MATCH_VERSION` to be the version
+of COmanage Match you want to deploy. See the
+[COmanage Match Release History](https://spaces.internet2.edu/display/COmanage+Match/Release+History)
+wiki page for the list of releases. We recommend using the latest release.
+
+Here is an example (but please check the wiki page for the latest release number):
+
+```
+export COMANAGE_MATCH_VERSION=1.0.0
+```
+
+* Define the shell variable `COMANAGE_MATCH_BASE_IMAGE_VERSION` to be the
+version of the base image you are about to build:
+
+```
+export COMANAGE_MATCH_BASE_IMAGE_VERSION=1
+```
+
+* Build the base COmanage Match image:
+
+```
+pushd comanage-match/comanage-match-base
+TAG="${COMANAGE_MATCH_VERSION}-${COMANAGE_MATCH_BASE_IMAGE_VERSION}"
+docker build \
+  --build-arg COMANAGE_MATCH_VERSION=${COMANAGE_MATCH_VERSION} \
+  -t comanage-match-base:${TAG} .
+popd
+```
+
+* Define the shell variable `COMANAGE_SHIBBOLETH_SP_BASE_IMAGE_VERSION`
+to be the version of the base Shibboleth SP image you are about to build:
+
+```
+export COMANAGE_SHIBBOLETH_SP_BASE_IMAGE_VERSION=1
+```
+
+* Build the base Shibboleth SP image:
+
+```
+pushd comanage-shibboleth-sp-base
+TAG="${COMANAGE_MATCH_SHIBBOLETH_SP_BASE_IMAGE_VERSION}"
+docker build \
+    -t comanage-match-shibboleth-sp-base:$TAG . 
+popd
+```
+
+* Define the shell variable `COMANAGE_MATCH_SHIBBOLETH_SP_IMAGE_VERSION`
+to be the version of the image you are about to build:
+
+```
+export COMANAGE_MATCH_SHIBBOLETH_SP_IMAGE_VERSION=1
+```
+
+* Build an image for COmanage Match that uses the Shibboleth SP
+for authentication:
+
+```
+pushd comanage-match/comanage-match-shibboleth-sp
+TAG="${COMANAGE_MATCH_VERSION}-shibboleth-sp-${COMANAGE_MATCH_SHIBBOLETH_SP_IMAGE_VERSION}"
+docker build \
+    --build-arg COMANAGE_MATCH_VERSION=${COMANAGE_MATCH_VERSION} \
+    --build-arg COMANAGE_MATCH_BASE_IMAGE_VERSION=${COMANAGE_MATCH_BASE_IMAGE_VERSION} \
+    --build-arg COMANAGE_SHIBBOLETH_SP_BASE_IMAGE_VERSION=${COMANAGE_SHIBBOLETH_SP_BASE_IMAGE_VERSION} \
+    -t comanage-match:$TAG .
+popd
+```
+
+* Define the shell variable `COMANAGE_MATCH_POSTGRES_IMAGE_VERSION`
+to be the version of the image you are about to build:
+
+```
+export COMANAGE_MATCH_POSTGRES_IMAGE_VERSION=1
+```
+
+* Build an image for PostgreSQL for COmanage Registry:
+
+```
+pushd comanage-match/comanage-match-postgres
+TAG="${COMANAGE_MATCH_POSTGRES_IMAGE_VERSION}"
+docker build \
+    -t comanage-match-postgres:${TAG} .
+popd
+```
+
+* Initialize the Docker Swarm:
+
+```
+docker swarm init
+```
+
+* Create secrets for the database root password, the COmanage Match database
+password, the HTTPS certificate (and CA signing chain) and private key files,
+and the Shibboleth SP encryption certificate and private key files (be sure
+to choose your own values and do not use the examples below):
+
+```
+echo "jPkrc3TUijfmT3vi1ZKw" | docker secret create postgres_password - 
+
+echo "ayFjKFHTre74A0k8k1mq" | docker secret create comanage_match_postgres_user_password - 
+
+echo "ayFjKFHTre74A0k8k1mq" | docker secret create comanage_match_database_user_password - 
+
+docker secret create https_cert_file fullchain.cert.pem
+
+docker secret create https_privkey_file privkey.pem
+
+docker secret create shibboleth_sp_encrypt_cert sp-encrypt-cert.pem
+
+docker secret create shibboleth_sp_encrypt_privkey sp-encrypt-key.pem
+```
+
+* Create directories on the Docker engine host(s) for state files
+and other files including the Shibboleth SP configuration files:
+
+```
+sudo mkdir -p /srv/docker/var/lib/postgresql/data
+sudo mkdir -p /srv/docker/srv/comanage-match/local
+sudo mkdir -p /srv/docker/etc/shibboleth
+```
+
+* Copy Shibboleth SP configuration files into place to be mounted
+into the running container. Your Shibboleth SP configuration should
+result in the primary identifier attribute you expect to be asserted by the SAML
+IdP(s) to populate `REMOTE_USER` so that it can be read by COmanage Match.
+A common choice is to populate `REMOTE_USER` with eduPersonPrincipalName, but
+the details will depend on your SAML federation choices.
+
+
+```
+cp shibboleth2.xml /srv/docker/etc/shibboleth/
+cp attribute-map.xml /srv/docker/etc/shibboleth/
+cp saml-metadata.xml /src/docker/etc/shibboleth/
+```
+
+* Define a shell variable for the first COmanage Match platform
+  administrator, for example:
+
+```
+export COMANAGE_MATCH_ADMIN_USERNAME=karel.novak@my.org
+```
+
+The username should be the value you expect to be asserted by the
+SAML IdP for the first platform administrator. The Shibboleth SP
+configuration should be such that the value is populated into
+`REMOTE_USER` where it will be read when the first platform 
+administrator logs into COmanage Match.
+
+* Define a shell variable with the fully-qualified domain name for
+the virtual host from which COmanage Match will be served. For 
+example
+
+```
+export COMANAGE_MATCH_VIRTUAL_HOST_FQDN=match.my.org
+```
+
+* Create a Docker Swarm services stack description (compose) file in YAML format:
+
+```
+version: '3.1'
+
+services:
+
+    comanage-match-database:
+        image: comanage-match-postgres:${COMANAGE_MATCH_POSTGRES_IMAGE_VERSION}
+        volumes:
+            - /srv/docker/var/lib/postgresql/data:/var/lib/postgresql/data
+        environment:
+            - POSTGRES_PASSWORD_FILE=/run/secrets/postgres_password
+            - COMANAGE_MATCH_POSTGRES_USER_PASSWORD_FILE=/run/secrets/comanage_match_postgres_user_password
+        secrets:
+            - postgres_password
+            - comanage_match_postgres_user_password
+        networks:
+            - default
+        deploy:
+            replicas: 1
+
+    comanage-match:
+        image: comanage-match:${COMANAGE_MATCH_VERSION}-shibboleth-sp-${COMANAGE_MATCH_SHIBBOLETH_SP_IMAGE_VERSION}
+        volumes:
+            - /srv/docker/srv/comanage-match/local:/srv/comanage-match/local
+            - /srv/docker/etc/shibboleth/shibboleth2.xml:/etc/shibboleth/shibboleth2.xml
+            - /srv/docker/etc/shibboleth/attribute-map.xml:/etc/shibboleth/attribute-map.xml
+            - /srv/docker/etc/shibboleth/saml-metadata.xml:/etc/shibboleth/saml-metadata.xml
+        environment:
+            - COMANAGE_MATCH_ADMIN_USERNAME=${COMANAGE_MATCH_ADMIN_USERNAME}
+            - COMANAGE_MATCH_DATASOURCE=Database/Postgres
+            - COMANAGE_MATCH_DATABASE_USER_PASSWORD_FILE=/run/secrets/comanage_match_database_user_password
+            - COMANAGE_MATCH_VIRTUAL_HOST_FQDN=${COMANAGE_MATCH_VIRTUAL_HOST_FQDN}
+            - HTTPS_CERT_FILE=/run/secrets/https_cert_file
+            - HTTPS_PRIVKEY_FILE=/run/secrets/https_privkey_file
+            - SHIBBOLETH_SP_ENCRYPT_CERT=/run/secrets/shibboleth_sp_encrypt_cert
+            - SHIBBOLETH_SP_ENCRYPT_PRIVKEY=/run/secrets/shibboleth_sp_encrypt_privkey
+        secrets:
+            - comanage_match_database_user_password
+            - https_cert_file
+            - https_privkey_file
+            - shibboleth_sp_encrypt_cert
+            - shibboleth_sp_encrypt_privkey
+        networks:
+            - default
+        ports:
+            - "80:80"
+            - "443:443"
+        deploy:
+            replicas: 1
+
+secrets:
+    comanage_match_database_user_password:
+        external: true
+    comanage_match_postgres_user_password:
+        external: true
+    postgres_password:
+        external: true
+    shibboleth_sp_encrypt_cert:
+        external: true
+    shibboleth_sp_encrypt_privkey:
+        external: true
+    https_cert_file:
+        external: true
+    https_privkey_file:
+        external: true
+```
+
+* Deploy the COmanage Match service stack:
+
+```
+docker stack deploy --compose-file comanage-match-stack.yml comanage-match
+```
+
+Since this is the first initialization of the containers it will take some
+time for the database tables to be created. The Apache HTTP Server and
+Shibboleth SP daemons will not be started until the entrypoint scripts
+detect that the database has been initialized.
+
+You may monitor the progress of the database container using
+
+```
+docker service logs -f comanage-match-database
+```
+
+and the progress of the COmanage Match container using
+
+```
+docker service logs -f comanage-match
+```
+
+* After the Apache HTTP Server has started browse to port 443 on the host. 
+
+* Click `Login` to initiate a SAML authentication flow. After authenticating at
+  the SAML IdP the Shibboleth SP should consume the SAML assertion and populate
+  `REMOTE_USER` with the value for the username for the first platform
+  administrator.
+
+* Visit the [COmanage wiki](https://spaces.internet2.edu/display/COmanage/Match+Platform+Configuration)
+to learn how to create your first Matchgrid and begin using
+the platform.
+
+* To stop the services:
+```
+docker stack rm comanage-match
+```
diff --git a/docs/volumes-and-data-persistence.md b/docs/volumes-and-data-persistence.md
new file mode 100644
index 0000000..e3d146b
--- /dev/null
+++ b/docs/volumes-and-data-persistence.md
@@ -0,0 +1,66 @@
+<!--
+COmanage Docker documentation
+
+Portions licensed to the University Corporation for Advanced Internet
+Development, Inc. ("UCAID") under one or more contributor license agreements.
+See the NOTICE file distributed with this work for additional information
+regarding copyright ownership.
+
+UCAID licenses this file to you under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with the
+License. You may obtain a copy of the License at:
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+# COmanage Match Volumes and Data Persistence
+
+COmanage Match requires a relational database. See other documentation in 
+this repository for examples of how to orchestrate a COmanage Match container
+together with an container providing a relational database service, and for details on how
+to configure the COmanage Match container to connect to the database.
+
+Additionally COmanage Match *requires* a persistent directory into which
+a few files and a specific directory structure needed by COmanage Match
+will be written. 
+
+*The persistent directory must be provided either using a Docker volume
+or a bind mount.*
+
+The directory path inside the container that must be mounted
+is `/src/comanage-match/local`.
+
+For example to use a bind mount from the local Docker engine host:
+
+```
+sudo mkdir -p /opt/comanage-match-local
+```
+
+and then when instantiating the container
+
+```
+docker run -d \
+  --name comanage-match \
+  -v /opt/comanage-match-local:/srv/comanage-match/local \
+  -p 80:80 \
+  -p 443:443 \
+  comanage-match:1.0.0-shibboleth-sp-1
+```
+
+After the image is instantiated into a container for the first time
+the entrypoint script will create the necessary directory structure
+along with the `database.php` and other necessary files using
+database and other details found in 
+[environment variables](./comanage-match-common-environment-variables.md).
+
+*After the first instantiation of the container later restarts will not overwrite
+database configuration or any other details in the persistent directory, even if the
+values for the environment variables change*.
+
+