diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 54ce5b67e480b6a61150076b72e12107e096962a..8a45a938b16278be4359090a313cde4333daa57d 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -5,6 +5,7 @@ stages:
   - deploy rabbit
   - deploy GRB
   - deploy G2G
+  - deploy tile gen
   - deploy WMS
   - deploy WMTS
   - deploy Client
@@ -75,6 +76,24 @@ create geotiff storage:
     - if: $CREATE_STORAGE
       when: always
 
+create shapefile storage:
+  extends: .helm_based_job
+  stage: create storage
+  script:
+    - ns=$(./helpers/get_namespace.sh)
+    # copy secret kubeconfig to the mounted (pwd) directory
+    - cp $kubekorner_k3s_config .
+    - kubeconfig=$(basename $kubekorner_k3s_config)
+    - ./helpers/create_pvc.sh "$ns" "ci_geosphere-test/shapefiles-pvc.yaml" "geosphere-tile-gen-shapefiles" "$kubeconfig"
+  # this job doesn't actually need any artifacts from previous jobs
+  dependencies: []
+  rules:
+    - changes:
+        - ci_geosphere-test/shapefiles-pvc.yaml
+      when: always
+    - if: $CREATE_STORAGE
+      when: always
+
 .get_chart_tmpl:
   extends: .helm_based_job
   stage: get chart
@@ -123,6 +142,12 @@ get_chart_geo2grid:
     SUBCOMP_REPOS: "geosphere-geo2grid"
     SUBCOMP_CHART_DIR: "cspp-geo-geo2grid"
 
+get_chart_tilegen:
+  extends: .get_chart_tmpl
+  variables:
+    SUBCOMP_REPOS: "geosphere-tile-gen"
+    SUBCOMP_CHART_DIR: "geosphere-tile-gen"
+
 get_chart_mapserver:
   extends: .get_chart_tmpl
   variables:
@@ -240,6 +265,43 @@ deploy_geo2grid_g16_radf:
       when: never
     - when: on_success
 
+.deploy_tile_gen:
+  environment:
+    name: geosphere-test
+    url: http://geosphere-test.ssec.wisc.edu
+  variables:
+    DEPLOY_SUFFIX: ""
+  extends: .helm_based_job
+  stage: deploy tile gen
+  script:
+    - ./helpers/deploy_tile_gen.sh "$DEPLOY_SUFFIX"
+  dependencies:
+    - get_chart_tilegen
+  rules:
+    - if: '$kubekorner_k3s_config == ""'
+      when: never
+    - when: on_success
+
+deploy_tile_gen_g16_radf:
+  extends: .deploy_tile_gen
+  variables:
+    DEPLOY_SUFFIX: "-g16-radf"
+
+deploy_tile_gen_g16_radc:
+  extends: .deploy_tile_gen
+  variables:
+    DEPLOY_SUFFIX: "-g16-radc"
+
+#deploy_tile_gen_g16_radm1:
+#  extends: .deploy_tile_gen
+#  variables:
+#    DEPLOY_SUFFIX: "-g16-radm1"
+#
+#deploy_tile_gen_g16_radm2:
+#  extends: .deploy_tile_gen
+#  variables:
+#    DEPLOY_SUFFIX: "-g16-radm2"
+
 deploy_mapserver:
   environment:
     name: geosphere-test
diff --git a/ci_geosphere-test/shapefiles-pvc.yaml b/ci_geosphere-test/shapefiles-pvc.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..d8a812c9351cf7582d1f00fbe81287546e7ca430
--- /dev/null
+++ b/ci_geosphere-test/shapefiles-pvc.yaml
@@ -0,0 +1,12 @@
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+  name: geosphere-tile-gen-shapefiles
+  labels: {}
+spec:
+  accessModes:
+    - ReadWriteOnce
+  resources:
+    requests:
+      storage: 2Gi
+  storageClassName: "longhorn"
diff --git a/ci_geosphere-test/values-mapserver.yaml b/ci_geosphere-test/values-mapserver.yaml
index 242c81aabe0967377344df6d4150a647c619376e..f4204db93a32d68f8e84c2130f12c1d4b020dd48 100644
--- a/ci_geosphere-test/values-mapserver.yaml
+++ b/ci_geosphere-test/values-mapserver.yaml
@@ -1,12 +1,3 @@
-rabbitIn:
-  host: "geosphere-rabbit-rabbitmq"
-  username: "user"
-  passwordSecret: "geosphere-rabbit-rabbitmq"
-  topic: "data.goes.g16.abi.*.l1b.geotiff.all.complete"
-rabbitOut:
-  host: "geosphere-rabbit-rabbitmq"
-  username: "user"
-  passwordSecret: "geosphere-rabbit-rabbitmq"
 source:
   #  s3Endpoint: "http://geosphere-minio:9000"
   existingClaim: "cspp-geo-geo2grid"
diff --git a/ci_geosphere-test/values-tile-gen-g16-radc.yaml b/ci_geosphere-test/values-tile-gen-g16-radc.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..8b7e60c77f8eb9d2161f10a7e627c92fde951a20
--- /dev/null
+++ b/ci_geosphere-test/values-tile-gen-g16-radc.yaml
@@ -0,0 +1,12 @@
+rabbitIn:
+  host: "geosphere-rabbit-rabbitmq"
+  username: "user"
+  passwordSecret: "geosphere-rabbit-rabbitmq"
+  topic: "data.goes.g16.abi.radf.l1b.geotiff.all.complete"
+rabbitOut:
+  host: "geosphere-rabbit-rabbitmq"
+  username: "user"
+  passwordSecret: "geosphere-rabbit-rabbitmq"
+source:
+  #  s3Endpoint: "http://geosphere-minio:9000"
+  existingClaim: "geosphere-tile-gen-shapefiles"
diff --git a/ci_geosphere-test/values-tile-gen-g16-radf.yaml b/ci_geosphere-test/values-tile-gen-g16-radf.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..8b7e60c77f8eb9d2161f10a7e627c92fde951a20
--- /dev/null
+++ b/ci_geosphere-test/values-tile-gen-g16-radf.yaml
@@ -0,0 +1,12 @@
+rabbitIn:
+  host: "geosphere-rabbit-rabbitmq"
+  username: "user"
+  passwordSecret: "geosphere-rabbit-rabbitmq"
+  topic: "data.goes.g16.abi.radf.l1b.geotiff.all.complete"
+rabbitOut:
+  host: "geosphere-rabbit-rabbitmq"
+  username: "user"
+  passwordSecret: "geosphere-rabbit-rabbitmq"
+source:
+  #  s3Endpoint: "http://geosphere-minio:9000"
+  existingClaim: "geosphere-tile-gen-shapefiles"
diff --git a/helpers/deploy_tile_gen.sh b/helpers/deploy_tile_gen.sh
new file mode 100644
index 0000000000000000000000000000000000000000..b4b5f08dc64662b37b87ec4b62f5b59fd965ff65
--- /dev/null
+++ b/helpers/deploy_tile_gen.sh
@@ -0,0 +1,23 @@
+#!/usr/bin/env bash
+
+set -e
+
+if [ $# -ne 1 ]; then
+    echo "Usage: ./helpers/deploy_tile_gen.sh <deploy_suffix>"
+    exit 1
+fi
+
+# Example: -g16-radf
+deploy_suffx="$1"
+
+ns=$(./helpers/get_namespace.sh)
+cd geosphere-tile-gen/chart
+source geosphere-tile-gen/cibuild.env
+# copy secret kubeconfig to the mounted (pwd) directory
+cp $kubekorner_k3s_config .
+kubeconfig=$(basename $kubekorner_k3s_config)
+echo "Deploying version $docker_tag to cluster namespace $ns"
+# copy extra values files to the local directory (where helm has access via docker mount)
+cp ../../ci_geosphere-test/values-tile-gen${deploy_suffix}.yaml .
+# namespace names are the same as domain names
+helm upgrade -v 2 --install --kubeconfig $kubeconfig --namespace $ns -f values-tile-gen${deploy_suffx}.yaml geosphere-tile-gen${deploy_suffx} geosphere-tile-gen/