4 minutes
Spring Boot on a Raspberry Pi using Docker
I guess it’s obvious from my other posts that I like playing with Raspberry Pi’s, so I decided to try and run a Spring Boot REST service on a Raspberry Pi using Docker. For this example I am using a Raspberry Pi 3 and my laptop is a linux machine.
The Spring Boot REST service
There is no special setup needed here, so if you already have a REST service you can use that, otherwise you can use the Spring Initializr to create a basic project. I used a maven project, with the latest stable Spring Boot version, Jar packaging, Java 8 and added Spring Web as a dependency. Download the zip, open it in your favorite editor and since our goal is to test the Docker container on the Raspberry Pi, let’s just create a basic controller named let’s say DemoRestController.java with the following code:
package com.example.demo;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(value ="/demo")
class DemoRestController {
@RequestMapping("/")
public String index() {
return "My Demo!";
}
}
Now you can test it by running the application and then open the web browser and go to:
http://localhost:8080/demo/
Next would be to package the application into a JAR file and since I am using Intellij and Maven I will just use the IDE
or mvn package
command to package the compiled code in a JAR which will be located in the target folder under the name
demo-0.0.1-SNAPSHOT.jar
Building a Docker Image
If you are already familiar with building Docker images, there is nothing special here. The base image is the important part. Let’s shortly see how this is done. In order to create a Docker image we need the well known Dockerfile (if it’s your first time working with such files, pay attention to naming of the file, for example DockerFile will not work). Create a Dockerfile in the root of your project and add the following:
FROM hypriot/rpi-java
ADD /target/demo-0.0.1-SNAPSHOT.jar /opt/demo-0.0.1-SNAPSHOT.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/opt/demo-0.0.1-SNAPSHOT.jar"]
Let’s see what this means:
- FROM: specifies which base image will be used to build the container. This image is compatible with Raspberry Pi and contains Java 8.
- ADD: copies the compiled and packaged code, so the JAR file from the local machine to the container filesystem
- EXPOSE: maps the specified port on the container with the outside host which in our case will be the Raspberry Pi
- ENTRYPOINT: will run our JAR file, which in other words, is set as the default application when the container is created using this image
Next would be to build the Docker image and get this image on the Raspberry Pi. There are a few options to do that.
If you are more familiar with docker, you already probably have your own way of doing such things, for example using a local registry so that you can push images between machines. This will require some extra configurations like enabling insecure-registry.
For someone less familiar with all this, just create a free account on dockerhub and push your image there, and then pull it on your Raspberry Pi.
First build and tag the image from the root of your project where the Dockerfile exists:
docker build -t <your-dockerhub-user-id>/demo .
You can check that the image exists by listing the images with:
docker image list
Now login to dockerhub by running the following command and enter your user and pass:
docker login
Next just push the image to dockerhub:
docker push <your-dockerhub-user-id>/demo
Now you should see the image on dockerhub by navigating to your profile.
Notice: If you check the build os/arch for this image
it will not show arm
, instead will show your local machine arch (my case linux) since we didn’t build a multi-architecture image.
This was not a problem with my setup (a linux machine) and the base image being arm
compatible, but if this will be a problem
in your case you need to look into multi-architecture builds using tools like buildx
that I might cover in another post.
On the Raspberry Pi
At this stage I believe you already have the preferred OS running on your Pi, SSH is enabled and the internet connection is set up.
Next would be the Docker set up on the Pi, which I will not describe in detail here, but you can find more information on my other post Docker on Pi .
Let’s take the example where you managed to push the image to dockerhub. Now on your Raspberry Pi, all you have to do is pull the image:
docker pull <your-dockerhub-user-id>/demo
Then run it:
docker run -it -p 8080:8080 <your-dockerhub-user-id>/demo
Once the application is ready just open your browser and go to:
http://your-pi-ip:8080/demo/
The docker compose equivalent would be:
version: '3.3'
services:
demo:
ports:
- '8080:8080'
image: <your-dockerhub-user-id>/demo