diff --git a/examples/spring-boot-hot-reload/.project b/examples/spring-boot-hot-reload/.project
new file mode 100644
index 0000000000..5fadea0a71
--- /dev/null
+++ b/examples/spring-boot-hot-reload/.project
@@ -0,0 +1,17 @@
+
+
+ spring-boot-sample-devtools
+
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.m2e.core.maven2Nature
+
+
diff --git a/examples/spring-boot-hot-reload/.settings/org.eclipse.m2e.core.prefs b/examples/spring-boot-hot-reload/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000000..f897a7f1cb
--- /dev/null
+++ b/examples/spring-boot-hot-reload/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/examples/spring-boot-hot-reload/README.md b/examples/spring-boot-hot-reload/README.md
new file mode 100644
index 0000000000..22d994fd7c
--- /dev/null
+++ b/examples/spring-boot-hot-reload/README.md
@@ -0,0 +1,45 @@
+# Spring Boot example project
+
+This example demonstrates Spring Boot running inside a Docker container (managed by a local Kubernetes cluster) with Spring Boot's dev tools enabled. We'll walk through live-restarting a Spring Boot service on compilation via Garden's hot reload functionality.
+
+## Prerequisites
+
+You'll need to have Java and [Maven](https://maven.apache.org/install.html) installed (follow the appropriate installation instructions for your platform).
+
+## Overview
+
+This project consists of a single module (in the `devtools` directory), which is a minimally modified version of the [Spring Boot devtools sample project found here](https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-devtools).
+
+We've changed the parent pom from `spring-boot-samples` to `spring-boot-starter-parent`, and added a dependency on `spring-boot-starter-actuator` (to enable the health check endpoint for k8s readiness and liveness probes). We've also removed the artificial 5 second delay that was added by the `slowRestart` method in `MyController`.
+
+## Usage
+
+First, run `mvn compile` in the `devtools` directory. This will download the service's dependencies and compile it. Afterwards, you should see the `target` directory appear (under `devtools`).
+
+Subsequent calls to `mvn compile` will be much faster, since the dependencies will have been cached by Maven.
+
+You can now deploy the service with hot reloading enabled e.g. by running
+
+```
+garden deploy --hot=devtools
+```
+
+This should produce output that's something like this:
+
+```
+Deploy 🚀
+
+✔ devtools → Building devtools:v-c6b9091207... → Done (
+took 0.4 sec)
+✔ devtools → Deploying version v-c6b9091207... → Done (
+took 67 sec)
+ → Ingress: http://spring-boot-hot-reload.local.app.garden
+🌻 Garden dashboard and API server running on http://localhost:50934
+
+🕑 Waiting for code changes
+```
+Open the ingress URL (http://spring-boot-hot-reload.local.app.garden above) in a web browser.
+
+Now, change the value of the `MESSAGE` constant in `devtools/src/main/java/sample/devtools/Message.java` to something else than `"Message"`, and run `mvn compile` (again in the `devtools` directory).
+
+This should trigger a hot reload. Refresh the the browser tab opened earlier, and you should see the change you made reflected in the header text.
\ No newline at end of file
diff --git a/examples/spring-boot-hot-reload/devtools/.gardenignore b/examples/spring-boot-hot-reload/devtools/.gardenignore
new file mode 100644
index 0000000000..9603395f64
--- /dev/null
+++ b/examples/spring-boot-hot-reload/devtools/.gardenignore
@@ -0,0 +1 @@
+src/main/java/**/*
diff --git a/examples/spring-boot-hot-reload/devtools/.gitignore b/examples/spring-boot-hot-reload/devtools/.gitignore
new file mode 100644
index 0000000000..eb5a316cbd
--- /dev/null
+++ b/examples/spring-boot-hot-reload/devtools/.gitignore
@@ -0,0 +1 @@
+target
diff --git a/examples/spring-boot-hot-reload/devtools/Dockerfile b/examples/spring-boot-hot-reload/devtools/Dockerfile
new file mode 100644
index 0000000000..2b31d88a17
--- /dev/null
+++ b/examples/spring-boot-hot-reload/devtools/Dockerfile
@@ -0,0 +1,16 @@
+FROM maven:3.6.0-jdk-11-slim
+WORKDIR /app
+
+COPY pom.xml /app/pom.xml
+RUN mvn dependency:resolve
+
+RUN mkdir -p /app/target
+COPY src /app/src
+# RUN mvn install
+
+ENV JVM_OPTS "-XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=1"
+RUN mvn install
+# RUN mvn compile
+CMD ["mvn", "spring-boot:run"]
+
+EXPOSE 8080
diff --git a/examples/spring-boot-hot-reload/devtools/garden.yml b/examples/spring-boot-hot-reload/devtools/garden.yml
new file mode 100644
index 0000000000..55eae5c794
--- /dev/null
+++ b/examples/spring-boot-hot-reload/devtools/garden.yml
@@ -0,0 +1,21 @@
+module:
+ description: Spring Boot devtools-sample module
+ type: container
+ name: devtools
+ hotReload:
+ sync:
+ - target: /app/target
+ source: target
+ services:
+ - name: devtools
+ ports:
+ - name: http
+ containerPort: 8080
+ servicePort: 80
+ healthCheck:
+ httpGet:
+ path: /actuator/health
+ port: http
+ ingresses:
+ - path: /
+ port: http
diff --git a/examples/spring-boot-hot-reload/devtools/pom.xml b/examples/spring-boot-hot-reload/devtools/pom.xml
new file mode 100755
index 0000000000..be536326d7
--- /dev/null
+++ b/examples/spring-boot-hot-reload/devtools/pom.xml
@@ -0,0 +1,49 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.1.3.RELEASE
+
+ spring-boot-sample-devtools
+ Spring Boot Developer Tools Sample
+ Spring Boot Developer Tools Sample
+
+ ${basedir}/../..
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-thymeleaf
+
+
+ org.springframework.boot
+ spring-boot-devtools
+
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
diff --git a/examples/spring-boot-hot-reload/devtools/src/main/java/sample/devtools/Message.java b/examples/spring-boot-hot-reload/devtools/src/main/java/sample/devtools/Message.java
new file mode 100755
index 0000000000..24340365ed
--- /dev/null
+++ b/examples/spring-boot-hot-reload/devtools/src/main/java/sample/devtools/Message.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2012-2018 the original author or authors.
+ *
+ * Licensed 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.
+ */
+
+package sample.devtools;
+
+public final class Message {
+
+ /**
+ * Sample message.
+ */
+ public static String MESSAGE = "Message";
+
+ private Message() {
+ }
+
+}
diff --git a/examples/spring-boot-hot-reload/devtools/src/main/java/sample/devtools/MyController.java b/examples/spring-boot-hot-reload/devtools/src/main/java/sample/devtools/MyController.java
new file mode 100755
index 0000000000..5f55913f17
--- /dev/null
+++ b/examples/spring-boot-hot-reload/devtools/src/main/java/sample/devtools/MyController.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2012-2016 the original author or authors.
+ *
+ * Licensed 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.
+ */
+
+package sample.devtools;
+
+import java.util.Date;
+
+import javax.annotation.PostConstruct;
+import javax.servlet.http.HttpSession;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.servlet.ModelAndView;
+
+@Controller
+public class MyController {
+
+ @GetMapping("/")
+ public ModelAndView get(HttpSession session) {
+ Object sessionVar = session.getAttribute("var");
+ if (sessionVar == null) {
+ sessionVar = new Date();
+ session.setAttribute("var", sessionVar);
+ }
+ ModelMap model = new ModelMap("message", Message.MESSAGE)
+ .addAttribute("sessionVar", sessionVar);
+ return new ModelAndView("hello", model);
+ }
+
+}
diff --git a/examples/spring-boot-hot-reload/devtools/src/main/java/sample/devtools/SampleDevToolsApplication.java b/examples/spring-boot-hot-reload/devtools/src/main/java/sample/devtools/SampleDevToolsApplication.java
new file mode 100755
index 0000000000..e10f482e0d
--- /dev/null
+++ b/examples/spring-boot-hot-reload/devtools/src/main/java/sample/devtools/SampleDevToolsApplication.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2012-2016 the original author or authors.
+ *
+ * Licensed 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.
+ */
+
+package sample.devtools;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class SampleDevToolsApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(SampleDevToolsApplication.class, args);
+ }
+
+}
diff --git a/examples/spring-boot-hot-reload/devtools/src/main/resources/application.properties b/examples/spring-boot-hot-reload/devtools/src/main/resources/application.properties
new file mode 100755
index 0000000000..c4d296d5b8
--- /dev/null
+++ b/examples/spring-boot-hot-reload/devtools/src/main/resources/application.properties
@@ -0,0 +1,5 @@
+# Enable remote support, for local development you don't need this line
+spring.devtools.remote.secret=secret
+management.endpoint.health.enabled=true
+management.endpoints.web.exposure.include=health
+# management.endpoints.web.exposure.include=health,info
\ No newline at end of file
diff --git a/examples/spring-boot-hot-reload/devtools/src/main/resources/public/public.txt b/examples/spring-boot-hot-reload/devtools/src/main/resources/public/public.txt
new file mode 100755
index 0000000000..e258b6c5c8
--- /dev/null
+++ b/examples/spring-boot-hot-reload/devtools/src/main/resources/public/public.txt
@@ -0,0 +1 @@
+public file
diff --git a/examples/spring-boot-hot-reload/devtools/src/main/resources/static/css/application.css b/examples/spring-boot-hot-reload/devtools/src/main/resources/static/css/application.css
new file mode 100755
index 0000000000..1f83e00900
--- /dev/null
+++ b/examples/spring-boot-hot-reload/devtools/src/main/resources/static/css/application.css
@@ -0,0 +1,9 @@
+h1 {
+ color: green;
+}
+
+.content {
+ font-family: sans-serif;
+ border-top: 3px solid red;
+ padding-top: 30px;
+}
diff --git a/examples/spring-boot-hot-reload/devtools/src/main/resources/templates/hello.html b/examples/spring-boot-hot-reload/devtools/src/main/resources/templates/hello.html
new file mode 100755
index 0000000000..bd6fb8a7f2
--- /dev/null
+++ b/examples/spring-boot-hot-reload/devtools/src/main/resources/templates/hello.html
@@ -0,0 +1,23 @@
+
+
+
+ Hello
+
+
+ Header
+
+
Session Var
+ Lorem ipsum dolor sit amet,
+ consectetur adipiscing elit. Cras ut fringilla augue, quis dictum
+ turpis. Sed tincidunt mi vel euismod viverra. Nulla facilisi.
+ Suspendisse mauris dolor, egestas ac leo at, porttitor ullamcorper
+ leo. Suspendisse consequat, justo ut rutrum interdum, nibh massa
+ semper dui, id sagittis tellus lectus at nibh. Etiam at scelerisque
+ nisi. Quisque vel eros tempor, fermentum sapien sed, gravida neque.
+ Fusce interdum sed dolor a semper. Morbi porta mauris a velit laoreet
+ viverra. Praesent et tellus vehicula, sagittis mi quis, faucibus urna.
+ Ut diam tortor, vehicula eget aliquam eget, elementum a odio. Fusce at
+ nisl sapien. Suspendisse potenti.
+
+
+
diff --git a/examples/spring-boot-hot-reload/devtools/src/test/java/sample/devtools/SampleDevToolsApplicationIntegrationTests.java b/examples/spring-boot-hot-reload/devtools/src/test/java/sample/devtools/SampleDevToolsApplicationIntegrationTests.java
new file mode 100755
index 0000000000..88ce1286b8
--- /dev/null
+++ b/examples/spring-boot-hot-reload/devtools/src/test/java/sample/devtools/SampleDevToolsApplicationIntegrationTests.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2012-2018 the original author or authors.
+ *
+ * Licensed 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.
+ */
+
+package sample.devtools;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.boot.test.web.client.TestRestTemplate;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Integration tests for {@link SampleDevToolsApplication}.
+ *
+ * @author Andy Wilkinson
+ * @author Phillip Webb
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
+public class SampleDevToolsApplicationIntegrationTests {
+
+ @Autowired
+ private TestRestTemplate restTemplate;
+
+ @Test
+ public void testStaticResource() {
+ ResponseEntity entity = this.restTemplate
+ .getForEntity("/css/application.css", String.class);
+ assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
+ assertThat(entity.getBody()).contains("color: green;");
+ }
+
+ @Test
+ public void testPublicResource() {
+ ResponseEntity entity = this.restTemplate.getForEntity("/public.txt",
+ String.class);
+ assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
+ assertThat(entity.getBody()).contains("public file");
+ }
+
+ @Test
+ public void testClassResource() {
+ ResponseEntity entity = this.restTemplate
+ .getForEntity("/application.properties", String.class);
+ assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
+ }
+
+}
diff --git a/examples/spring-boot-hot-reload/garden.yml b/examples/spring-boot-hot-reload/garden.yml
new file mode 100644
index 0000000000..36d4332afb
--- /dev/null
+++ b/examples/spring-boot-hot-reload/garden.yml
@@ -0,0 +1,6 @@
+project:
+ name: spring-boot-hot-reload
+ environments:
+ - name: local
+ providers:
+ - name: local-kubernetes