diff --git a/mapserver/Dockerfile b/mapserver/Dockerfile
index 63fb289ff02ecbe57fd1c94b17cb6a50362ddece..7bb97b5f5066e350db4f5e8fc6ca47ab40474ed5 100644
--- a/mapserver/Dockerfile
+++ b/mapserver/Dockerfile
@@ -87,6 +87,8 @@ RUN ln -s /usr/local/bin/mapserv /usr/lib/cgi-bin/mapserv && \
     chown ${APACHE_RUN_USER}:${APACHE_RUN_GROUP} /usr/lib/cgi-bin/* && \
     chown -h ${APACHE_RUN_USER}:${APACHE_RUN_GROUP} /usr/lib/cgi-bin/*
 
+RUN pip3 install jinja2
+COPY render.py run.sh abi_l1b_template.map /work/
 COPY mapfiles/ /work/mapfiles/
 COPY html/ /var/www/html/
 
@@ -103,4 +105,4 @@ RUN apache2ctl configtest
 STOPSIGNAL WINCH
 
 EXPOSE 80
-CMD ["/usr/sbin/apache2ctl", "-DFOREGROUND"]
+CMD ["/work/run.sh"]
diff --git a/mapserver/abi_l1b_template.map b/mapserver/abi_l1b_template.map
new file mode 100644
index 0000000000000000000000000000000000000000..44b7d3f3a191574d11761604ac7ad1dcf89e63ea
--- /dev/null
+++ b/mapserver/abi_l1b_template.map
@@ -0,0 +1,55 @@
+MAP
+  NAME "{{ platform_long_name }} ABI {{ sector_long_name }} L1b Layers"
+  STATUS ON
+  IMAGETYPE rgb
+  SIZE 256 256
+  EXTENT -5434894.885 -5434894.885 5434894.885 5434894.885
+
+  PROJECTION
+    "{{ projection }}"
+  END
+
+  WEB
+    METADATA
+      "wms_title" "CSPP Geo Geo2Grid Viewer"
+      "wms_onlineresource" "https://myhost/mapserv"
+      "wms_enable_request" "*"
+    END
+  END
+
+  INCLUDE '/work/mapfiles/output_formats.map'
+
+  {% for product in products %}
+  # {{ product.replace('_', ' ').title() }} #
+
+  LAYER
+    NAME "{{ product }}_index"
+    TYPE TILEINDEX
+    DATA "{{ layer_base_dir }}/{{ platform }}/abi/{{ sector }}/{{ product }}/{{ product }}"
+  END
+
+  LAYER
+    NAME "{{ product }}"
+    TYPE RASTER
+    TILEITEM "location"
+    TILEINDEX "{{ product }}_index"
+    # Comment below to default to transparency
+    #OFFSITE 0 0 0
+    PROJECTION
+      "{{ projection }}"
+    END
+    PROCESSING "RESAMPLE=AVERAGE"
+    METADATA
+      "wms_title" "{{ platform_long_name }} ABI {{ product.replace('_', ' ').title() }}"
+      "wms_extent" "-180 -90 180 90"
+      "wms_timeextent" "2017-01-01/2040-12-31"
+      "wms_timeformat" "YYYY-MM-DDTHH:MM:SS"
+      "wms_timeitem" "time" # time is a metadata item
+      "wms_timedefault" "2019-12-12T19:20:18"
+      "wms_enable_request" "*"
+    END
+    FILTER (`[time]` = `2019-12-12T19:20:18`)
+  END # goes raster layer ends here
+  {% endfor %}
+
+END # end of map file
diff --git a/mapserver/mapfiles/g16_abi_radf_l1b.map b/mapserver/mapfiles/g16_abi_radf_l1b.map
deleted file mode 100644
index 8c5adad76088bdc1533c2a5833fa824b81e96d6f..0000000000000000000000000000000000000000
--- a/mapserver/mapfiles/g16_abi_radf_l1b.map
+++ /dev/null
@@ -1,113 +0,0 @@
-MAP
-  NAME "GOES-16 ABI Full Disk L1b Layers"
-  STATUS ON
-  IMAGETYPE rgba
-  SIZE 256 256
-  EXTENT -5434894.885 -5434894.885 5434894.885 5434894.885
-  #EXTENT         -180 -90 180 90
-  
-  PROJECTION
-    "init=epsg:930916"
-  END
-
-  WEB
-    METADATA
-      "wms_title" "CSPP Geo Geo2Grid Viewer"
-      "wms_onlineresource" "https://myhost/mapserv"
-      "wms_enable_request" "*"
-    END
-  END
-
-  INCLUDE '/work/mapfiles/output_formats.map'
-
-  ##############
-  # True Color #
-  ##############
-
-  LAYER
-    NAME "true_color_index"
-    TYPE TILEINDEX
-    DATA "/data/tiles/g16/abi/radf/true_color/true_color"
-  END
-
-  LAYER
-    NAME    "true_color"
-    TYPE    RASTER
-    TILEITEM "location"
-    TILEINDEX "true_color_index"
-    # Comment below to default to transparency
-    # OFFSITE 0 0 0
-    PROJECTION
-      "init=epsg:930916"
-    END
-    METADATA
-      "wms_title" "GOES-16 ABI True Color"
-      "wms_extent" "-180 -90 180 90"
-      "wms_timeextent" "2017-01-01/2020-12-31"
-      "wms_timeformat" "YYYY-MM-DDTHH:MM:SS"
-      "wms_timeitem" "time" # time is a metadata item
-      "wms_timedefault" "2019-12-12T19:20:18"
-      "wms_enable_request" "*"
-    END
-    FILTER (`[time]` = `2019-12-12T19:20:18`)
-  END # goes raster layer ends here
-
-  ######################
-  # True Color Lat/Lon #
-  ######################
-
-  LAYER
-    NAME "true_color_index_ll"
-    TYPE TILEINDEX
-    DATA "/data/tiles/g16/abi/radf_ll/true_color_ll/true_color_ll"
-  END
-
-  LAYER
-    NAME    "true_color_ll"
-    TYPE    RASTER
-    TILEITEM "location"
-    TILEINDEX "true_color_index_ll"
-    # Comment below to default to transparency
-    # OFFSITE 0 0 0
-    PROJECTION
-      "init=epsg:4326"
-    END
-    METADATA
-      "wms_title" "GOES-16 ABI True Color"
-      "wms_extent" "-180 -90 180 90"
-      "wms_timeextent" "2017-01-01/2020-12-31"
-      "wms_timeformat" "YYYY-MM-DDTHH:MM:SS"
-      "wms_timeitem" "time" # time is a metadata item
-      "wms_timedefault" "2019-12-12T19:20:18"
-      "wms_enable_request" "*"
-    END
-    FILTER (`[time]` = `2019-12-12T19:20:18`)
-  END # goes raster layer ends here
-
-  ###################
-  # True Color Fake #
-  ###################
-
-  LAYER
-    NAME    "true_color_test"
-    TYPE    RASTER
-    TILEITEM "location"
-    TILEINDEX "true_color_index"
-    # Comment below to default to transparency
-    # OFFSITE 0 0 0
-    PROJECTION
-        "init=epsg:930916"
-    END
-    METADATA
-      "wms_title" "GOES-16 ABI True Color"
-      "wms_extent" "-180 -90 180 90"
-      "wms_timeextent" "2017-01-01/2020-12-31"
-      "wms_timeformat" "YYYY-MM-DDTHH:MM:SS"
-      "wms_timeitem" "time" # time is a metadata item
-      "wms_timedefault" "2019-12-12T19:20:18"
-      "wms_enable_request" "*"
-    END
-    FILTER (`[time]` = `2019-12-12T19:20:18`)
-  END # goes raster layer ends here
-
-END # end of map file
diff --git a/mapserver/mapfiles/output_formats.map b/mapserver/mapfiles/output_formats.map
index 86d37cf271216826856529f0e3146ff5bf2f2df7..3076db4d77b045d683b010134feeb4d512dd3f1e 100644
--- a/mapserver/mapfiles/output_formats.map
+++ b/mapserver/mapfiles/output_formats.map
@@ -13,8 +13,8 @@
     NAME "rgb"
     DRIVER AGG/PNG
     MIMETYPE "image/png"
-    IMAGEMODE RGBA
-    TRANSPARENT ON
+    IMAGEMODE RGB
+    TRANSPARENT OFF
     EXTENSION "png"
   END
 
diff --git a/mapserver/mapfiles/overlays.map b/mapserver/mapfiles/overlays.map
index 20117becf5c247216fd7413610c78c0725df0fcc..1ccc53540e7351592f31517d233b30d60b60eef0 100644
--- a/mapserver/mapfiles/overlays.map
+++ b/mapserver/mapfiles/overlays.map
@@ -4,7 +4,7 @@ MAP
   MAXSIZE 5000
   SIZE 1024 1024
   IMAGECOLOR 128 128 128
-  IMAGETYPE rgb
+  IMAGETYPE rgba
   EXTENT -5434894.885 -5434894.885 5434894.885 5434894.885
   FONTSET "/work/mapfiles/fonts.list"
 
diff --git a/mapserver/render.py b/mapserver/render.py
new file mode 100644
index 0000000000000000000000000000000000000000..0c1864ad495c69a8202d525a633c0fd8f66b111a
--- /dev/null
+++ b/mapserver/render.py
@@ -0,0 +1,82 @@
+#!/usr/bin/env python3
+"""Convert a template mapfile config to a full config.
+
+We do this rendering when the container is started to allow for complete
+control per mapserver instance (even though there is usually only one).
+
+"""
+
+import os
+import sys
+import jinja2
+
+
+sectors = "radm1 radm2 radc radf"
+sectors = os.getenv("WMS_SECTORS", sectors).split(" ")
+products = ["C{:02d}".format(x) for x in range(1, 17)] + ["true_color"]
+products = os.getenv("WMS_PRODUCTS", " ".join(products)).split(" ")
+platforms = "g16 g17"
+platforms = os.getenv("WMS_PLATFORMS", platforms).split(" ")
+
+layer_base_dir = os.environ['LAYER_BASE_DIR']
+
+
+SECTOR_LONG_NAMES = {
+    'radm1': 'Mesoscale 1',
+    'radm2': 'Mesoscale 2',
+    'radc': 'CONUS',
+    'radf': 'Full disk',
+}
+
+PLATFORM_LONG_NAMES = {
+    'g16': 'GOES-16',
+    'g17': 'GOES-17',
+}
+
+PLATFORM_EPSGS = {
+    'g16': 'EPSG:930916',
+    'g17': 'EPSG:930917',
+}
+
+PLATFORM_POS_NAMES = {
+    'g16': 'GOES-EAST',
+    'g17': 'GOES-WEST',
+}
+
+LAYER_TO_FORMAT = {
+    'C01': 'gray',
+    'true_color': 'rgba'
+}
+
+
+def main():
+    import argparse
+    parser = argparse.ArgumentParser(description="Render mapfile template to complete mapfile config.")
+    parser.add_argument("template_fn",
+                        help="Template XML file to render")
+    parser.add_argument('output_pattern',
+                        help='Format string for each output mapfiles.')
+    args = parser.parse_args()
+
+    for platform in platforms:
+        for sector in sectors:
+            tmpl_vars = {
+                'sector': sector,
+                'platform': platform,
+                'products': products,
+                'layer_base_dir': layer_base_dir,
+                'platform_long_name': PLATFORM_LONG_NAMES[platform],
+                'sector_long_name': SECTOR_LONG_NAMES[sector],
+                'projection': "init=" + PLATFORM_EPSGS[platform].lower(),
+                'PLATFORM_EPSGS': PLATFORM_EPSGS,
+                'PLATFORM_POS_NAMES': PLATFORM_POS_NAMES,
+            }
+            output_fn = args.output_pattern.format(**tmpl_vars)
+
+            with open(args.template_fn, 'r') as tmpl_file, open(output_fn, 'w') as mapfile:
+                template = jinja2.Template(tmpl_file.read())
+                mapfile.write(template.render(tmpl_vars))
+
+
+if __name__ == "__main__":
+    sys.exit(main())
\ No newline at end of file
diff --git a/mapserver/run.sh b/mapserver/run.sh
new file mode 100755
index 0000000000000000000000000000000000000000..8f79599cdc8a6fd13ef91581db6c989f4eba2ead
--- /dev/null
+++ b/mapserver/run.sh
@@ -0,0 +1,14 @@
+#!/bin/bash -le
+
+# Load environment variable options to overwrite in the config
+export LAYER_BASE_DIR=${LAYER_BASE_DIR:-"/data/tiles"}
+
+# Update the mapcache.xml file with the real host and port name
+mf_tmpl="/work/abi_l1b_template.map"
+export WMS_PLATFORMS=${WMS_PLATFORMS:-"g16 g17"}
+export WMS_SECTORS=${WMS_SECTORS:-"radm1 radm2 radc radf"}
+python3 /work/render.py $mf_tmpl "/work/mapfiles/{platform}_abi_{sector}_l1b.map"
+
+/usr/sbin/apache2ctl configtest
+
+/usr/sbin/apache2ctl -DFOREGROUND