diff --git a/charms/horizon-k8s/src/charm.py b/charms/horizon-k8s/src/charm.py
index 4e214c60..4d2dfb16 100755
--- a/charms/horizon-k8s/src/charm.py
+++ b/charms/horizon-k8s/src/charm.py
@@ -87,6 +87,8 @@ def manage_plugins(
 class WSGIHorizonPebbleHandler(sunbeam_chandlers.WSGIPebbleHandler):
     """Horizon Pebble Handler."""
 
+    charm: "HorizonOperatorCharm"
+
     def init_service(self, context: sunbeam_core.OPSCharmContexts) -> None:
         """Enable and start WSGI service."""
         container = self.charm.unit.get_container(self.container_name)
@@ -95,6 +97,25 @@ class WSGIHorizonPebbleHandler(sunbeam_chandlers.WSGIPebbleHandler):
         exec(container, "a2disconf other-vhosts-access-log")
         super().init_service(context)
 
+    def files_changed(self, files: list[str]):
+        """Call django utilities when local_settings.py changes."""
+        logger.debug("Files changed: %r", files)
+        if (
+            self.charm.service_conf in files
+            and self.charm.ingress_public.ready
+        ):
+            logger.debug("local_settings.py changed, running django utilities")
+            container = self.charm.unit.get_container(self.container_name)
+            manage = "/usr/share/openstack-dashboard/manage.py"
+            exec(
+                container,
+                manage + " collectstatic --no-input",
+            )
+            exec(
+                container,
+                manage + " compress --force",
+            )
+
 
 class HorizonOperatorCharm(sunbeam_charm.OSBaseOperatorAPICharm):
     """Charm the service."""
diff --git a/charms/horizon-k8s/src/templates/local_settings.py.j2 b/charms/horizon-k8s/src/templates/local_settings.py.j2
index 3ebd179a..c1161e38 100644
--- a/charms/horizon-k8s/src/templates/local_settings.py.j2
+++ b/charms/horizon-k8s/src/templates/local_settings.py.j2
@@ -851,7 +851,7 @@ LOGIN_REDIRECT_URL='{{ ingress_public.ingress_path }}'
 ALLOWED_HOSTS = ['*']
 
 # Compress all assets offline as part of packaging installation
-#COMPRESS_OFFLINE = True
+COMPRESS_OFFLINE = True
 
 # DISALLOW_IFRAME_EMBED can be used to prevent Horizon from being embedded
 # within an iframe. Legacy browsers are still vulnerable to a Cross-Frame
diff --git a/charms/ovn-relay-k8s/src/charm.py b/charms/ovn-relay-k8s/src/charm.py
index c03f2403..a6ca1447 100755
--- a/charms/ovn-relay-k8s/src/charm.py
+++ b/charms/ovn-relay-k8s/src/charm.py
@@ -84,7 +84,8 @@ class OVNRelayPebbleHandler(ovn_chandlers.OVNPebbleHandler):
         NOTE: Override default to services being automatically started
         """
         self.setup_dirs()
-        self.write_config(context)
+        changes = self.write_config(context)
+        self.files_changed(changes)
         self.start_service()
 
 
diff --git a/ops-sunbeam/ops_sunbeam/container_handlers.py b/ops-sunbeam/ops_sunbeam/container_handlers.py
index f6c7d645..a47a6249 100644
--- a/ops-sunbeam/ops_sunbeam/container_handlers.py
+++ b/ops-sunbeam/ops_sunbeam/container_handlers.py
@@ -95,7 +95,7 @@ class PebbleHandler(ops.framework.Object):
 
     def write_config(
         self, context: sunbeam_core.OPSCharmContexts
-    ) -> List[str]:
+    ) -> list[str]:
         """Write configuration files into the container.
 
         Write self.container_configs into container if there contents
@@ -157,7 +157,8 @@ class PebbleHandler(ops.framework.Object):
         that service is ready for us.
         """
         self.setup_dirs()
-        self.write_config(context)
+        changes = self.write_config(context)
+        self.files_changed(changes)
         self.status.set(ActiveStatus(""))
 
     def default_container_configs(
@@ -314,6 +315,9 @@ class PebbleHandler(ops.framework.Object):
             logger.debug("Stopping all services")
             container.stop(*services.keys())
 
+    def files_changed(self, files: list[str]):
+        """Called when files have changed before restarting services."""
+
 
 class ServicePebbleHandler(PebbleHandler):
     """Container handler for containers which manage a service."""
@@ -326,6 +330,7 @@ class ServicePebbleHandler(PebbleHandler):
         """
         self.setup_dirs()
         files_changed = self.write_config(context)
+        self.files_changed(files_changed)
         if files_changed:
             self.start_service(restart=True)
         else:
@@ -460,6 +465,7 @@ class WSGIPebbleHandler(PebbleHandler):
             # ignore for now - pebble is raising an exited too quickly, but it
             # appears to work properly.
         files_changed.extend(self.write_config(context))
+        self.files_changed(files_changed)
         if files_changed:
             self.start_wsgi(restart=True)
         else:
diff --git a/ops-sunbeam/ops_sunbeam/ovn/container_handlers.py b/ops-sunbeam/ops_sunbeam/ovn/container_handlers.py
index d7ed8e07..24d9a62b 100644
--- a/ops-sunbeam/ops_sunbeam/ovn/container_handlers.py
+++ b/ops-sunbeam/ops_sunbeam/ovn/container_handlers.py
@@ -48,7 +48,8 @@ class OVNPebbleHandler(sunbeam_chandlers.ServicePebbleHandler):
         NOTE: Override default to services being automatically started
         """
         self.setup_dirs()
-        self.write_config(context)
+        changes = self.write_config(context)
+        self.files_changed(changes)
         self.status.set(ActiveStatus(""))
 
     @property