Deploying a Spring Boot App With MySQL on OpenShift
This article shows how to take an existing Spring Boot standalone project that uses MySQL and deploy it on Red Hat OpenShift. In the process, we'll create docker images which can be deployed to most container/cloud platforms. I'll discuss creating a Dockerfile, pushing the container image to an OpenShift registry, and finally creating running pods with the Spring Boot app deployed.
To develop and test using OpenShift on my local machine, I used Red Hat Container Development Kit (CDK), which provides a single-node OpenShift cluster running in a Red Hat Enterprise Linux VM, based on Minishift. You can run CDK on top of Windows, macOS, or Red Hat Enterprise Linux. For testing, I used Red Hat Enterprise Linux Workstation release 7.3. It should work on macOS, too.
To create the Spring Boot app, I used this article as a guide. I'm using an existing openshift/mysql-56-centos7 Docker image to deploy MySQL to OpenShift.
You can download the code used in this article from my personal github repo. In this article, I'll be building container images locally, so you'll need to be able to build the project locally with Maven. This example exposes a rest service using: com.sample.app.MainController.java.
In the repository, you'll find a Dockerfile in src/main/docker-files/
. The file creates a Docker image, having the Spring Boot application based on java8docker image as a base. While this is okay for testing, for production deployment you'd want to use images that are based on Red Hat Enterprise Linux.
Building the application:
- Use
mvn clean install
to build the project. - Copy the generated jar in the target folder to
src/main/docker-files
. When creating the Docker image, the application jar can be found at the same location. - Set the database username, password, and URL in
src/main/resources/application.properties
. Note: For OpenShift, it is recommended to pass these parameters into the container as environment variables.
Now start the CDK VM to get your local OpenShift cluster running.
1. Start the CDK VM using minishift start:
$ minishift start
2. Set your local environment for docker and the oc CLI:
$ eval $(minishift oc-env)
$ eval $(minishift docker-env)
Note: the above eval
commands will not work on Windows. See the CDK documentation for more information.
3. Login to OpenShift and Docker using the developer account:
$ oc login
$ docker login -u developer -p $(oc whoami -t) $(minishift openshift registry)
Now we'll build the container images.
1. Change the directory location to src/main/docker-files
within the project. Then, execute the following commands to build the container images. Note: The period (.) is required at the end of the Docker build command to indicate the current directory:
$ docker build -t springboot_mysql -f ./dockerfile_springboot_mysql .
Use the following command to view the container images that were created:
$ docker images
2. Add the tag springboot_mysql
to the image, and push it to the OpenShift registry:
$ docker tag springboot_mysql $(minishift openshift registry)/myproject/springboot_mysql
$ docker push $(minishift openshift registry)/myproject/springboot_mysql
3. Next, pull the OpenShift MySQL image, and create it as an OpenShift application which will initialize and run it. Refer to the documentation for more information:
docker pull openshift/mysql-56-centos7
oc new-app -e MYSQL_USER=root -e MYSQL_PASSWORD=root -e MYSQL_DATABASE=test openshift/mysql-56-centos7
4. Wait for the pod running MySQL to be ready. You can check the status with oc get pods
:
$ oc get pods
NAME READY STATUS RESTARTS AGE
mysql-56-centos7-1-nvth9 1/1 Running 0 3m
5. Next, ssh to the mysql pod and create a MySQL root user with full privileges:
$ oc rsh mysql-56-centos7-1-nvth9
sh-4.2$ mysql -u root
CREATE USER 'root'@'%' IDENTIFIED BY 'root';
Query OK, 0 rows affected (0.00 sec)
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
Query OK, 0 rows affected (0.00 sec)
FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
exit
6. Finally, initialize the Spring Boot app using imagestream springboot_mysql:
$ oc get svc
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
mysql-56-centos7 172.30.145.88 none 3306/TCP 8m
$ oc new-app -e spring_datasource_url=jdbc:mysql://172.30.145.88:3306/test springboot_mysql
$ oc get pods
NAME READY STATUS RESTARTS AGE
mysql-56-centos7-1-nvth9 1/1 Running 0 12m
springbootmysql-1-5ngv4 1/1 Running 0 9m
7. Check the pod logs:
oc logs -f springbootmysql-1-5ngv4
8. Next, expose the service as a route:
$ oc get svc
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
mysql-56-centos7 172.30.242.225 none 3306/TCP 14m
springbootmysql 172.30.207.116 none 8080/TCP 1m
$ oc expose svc springbootmysql
route "springbootmysql" exposed
$ oc get route
NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD
springbootmysql springbootmysql-myproject.192.168.42.182.nip.io springbootmysql 8080-tcp None
9. Test the application using curl
. You should see a list of all entries in the database table:
$ curl -v http://springbootmysql-myproject.192.168.42.182.nip.io/demo/all
10. Next, use curl
to create an entry in the db:
$ curl http://springbootmysql-myproject.192.168.42.182.nip.io/demo/add?name=SpringBootMysqlTest
Saved
11. View the updated list of entries in the database:
$ curl http://springbootmysql-myproject.192.168.42.182.nip.io/demo/all
[{"name":"UBUNTU 17.10 LTS","lastaudit":1502409600000,"id":1},{"name":"RHEL 7","lastaudit":1500595200000,"id":2},{"name":"Solaris 11","lastaudit":1502582400000,"id":3},{"name":"SpringBootTest","lastaudit":1519603200000,"id":4},{"name":"SpringBootMysqlTest","lastaudit":1519603200000,"id":5}
That's it!
I hope this article is helpful to you for migrating an existing spring-boot application to OpenShift. Just a note, in production environments, one should use Red Hat Supportable Images. This document is intended for development purposes only. It should assist you in creating spring-boot applications that run in containers; and in how to set up MySQL connectivity for spring-boot in OpenShift.